]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: vendor stop_signal.h
authorKefu Chai <tchaikov@gmail.com>
Sat, 1 Oct 2022 08:30:43 +0000 (16:30 +0800)
committerKefu Chai <tchaikov@gmail.com>
Sat, 1 Oct 2022 09:28:06 +0000 (17:28 +0800)
stop_signal.h is copied from seastar/apps/lib/stop_signal.hh. this
change copies it int our project so we can customize it in a following
commit. we will need to add an `abort_source` member to it.

the class `stop_signal` works great for us. but under some
circumstances, we also need to stop the crimson server programmatically
from the server itsef, for instance, per the request of monitor. in that
case, `stop_signal` cannot fulfill our needs, as the only thing which
can stop it is, SIGTERM or SIGTERM. we could send SIGINT to ourselves to
unblock `stop_signal::wait()`. but it would be better if we could leverage
`abort_source` for this purpose. for two reasons:

* `abort_source` allows use to cancel a "blocking" op.
  we have a couple background tasks in crimson, like `AdminSocket`'s
  accept and handle task, which could have been stopped by an
  `abort_source`. but now it checks for the `stop_gate` before accepting
  an incoming connection. this pattern cannot be always be repeated.
  because we cannot *abort* a "blocking" task. for instance, we use
  a homebrew `tri_mutex` to protect the read/write consistency of
  an obc, what if the server would need to stop when a request is
  still trying to acquire the lock? with the help of the `abort_source`,
  we should be able to either subscribe from the `abort_source`,
  and set an abort exception for each of the waiters. the same applies
  to other "blocking" calls like `shared_promise::get_shared_future()`,
  this allows us to abort the waiter before the promise is resolved.
  this could be handy if we need to abort potentially op which
  might take long and should be aborted when monitor wants to
  kill the osd instance.
* `abort_source` allows us to abort the services programmatically.
  this is the use case mentioned in the beginning of this commit
  message.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
src/crimson/osd/main.cc
src/crimson/osd/stop_signal.h [new file with mode: 0644]

index 18fee14aec54c842c60e3cc2b15f36b49edf5a1d..1eead7b924c0e9e67064447af3aa1ff99f4d5379 100644 (file)
@@ -8,7 +8,6 @@
 #include <fstream>
 #include <random>
 
-#include <seastar/apps/lib/stop_signal.hh>
 #include <seastar/core/app-template.hh>
 #include <seastar/core/print.hh>
 #include <seastar/core/prometheus.hh>
@@ -27,6 +26,7 @@
 #include "crimson/common/fatal_signal.h"
 #include "crimson/mon/MonClient.h"
 #include "crimson/net/Messenger.h"
+#include "crimson/osd/stop_signal.h"
 #include "global/pidfile.h"
 #include "osd.h"
 
diff --git a/src/crimson/osd/stop_signal.h b/src/crimson/osd/stop_signal.h
new file mode 100644 (file)
index 0000000..ccc340b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * This file is open source software, licensed to you under the terms
+ * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
+ * distributed with this work for additional information regarding copyright
+ * ownership.  You may not use this file except in compliance with the License.
+ *
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Copyright (C) 2020 Cloudius Systems, Ltd.
+ */
+
+#pragma once
+
+#include <seastar/core/sharded.hh>
+#include <seastar/core/reactor.hh>
+#include <seastar/core/condition-variable.hh>
+
+/// Seastar apps lib namespace
+
+namespace seastar_apps_lib {
+
+
+/// \brief Futurized SIGINT/SIGTERM signals handler class
+///
+/// Seastar-style helper class that allows easy waiting for SIGINT/SIGTERM signals
+/// from your app.
+///
+/// Example:
+/// \code
+/// #include <seastar/apps/lib/stop_signal.hh>
+/// ...
+/// int main() {
+/// ...
+/// seastar::thread th([] {
+///    seastar_apps_lib::stop_signal stop_signal;
+///    <some code>
+///    stop_signal.wait().get();  // this will wait till we receive SIGINT or SIGTERM signal
+/// });
+/// \endcode
+class stop_signal {
+    bool _caught = false;
+    seastar::condition_variable _cond;
+private:
+    void signaled() {
+        if (_caught) {
+            return;
+        }
+        _caught = true;
+        _cond.broadcast();
+    }
+public:
+    stop_signal() {
+        seastar::engine().handle_signal(SIGINT, [this] { signaled(); });
+        seastar::engine().handle_signal(SIGTERM, [this] { signaled(); });
+    }
+    ~stop_signal() {
+        // There's no way to unregister a handler yet, so register a no-op handler instead.
+        seastar::engine().handle_signal(SIGINT, [] {});
+        seastar::engine().handle_signal(SIGTERM, [] {});
+    }
+    seastar::future<> wait() {
+        return _cond.wait([this] { return _caught; });
+    }
+    bool stopping() const {
+        return _caught;
+    }
+};
+}