Skip to content

Commit

Permalink
signal: add seastar signal api
Browse files Browse the repository at this point in the history
Closes #2384
  • Loading branch information
tomershafir authored and xemul committed Aug 30, 2024
1 parent 3b0d5a5 commit c3e826a
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ add_library (seastar
include/seastar/core/shared_ptr_debug_helper.hh
include/seastar/core/shared_ptr_incomplete.hh
include/seastar/core/simple-stream.hh
include/seastar/core/signal.hh
include/seastar/core/slab.hh
include/seastar/core/sleep.hh
include/seastar/core/sstring.hh
Expand Down Expand Up @@ -715,6 +716,7 @@ add_library (seastar
src/core/sharded.cc
src/core/scollectd.cc
src/core/scollectd-impl.hh
src/core/signal.cc
src/core/systemwide_memory_barrier.cc
src/core/smp.cc
src/core/sstring.cc
Expand Down
9 changes: 5 additions & 4 deletions apps/lib/stop_signal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <seastar/core/sharded.hh>
#include <seastar/core/reactor.hh>
#include <seastar/core/condition-variable.hh>
#include <seastar/core/signal.hh>

/// Seastar apps lib namespace

Expand Down Expand Up @@ -61,13 +62,13 @@ private:
}
public:
stop_signal() {
seastar::engine().handle_signal(SIGINT, [this] { signaled(); });
seastar::engine().handle_signal(SIGTERM, [this] { signaled(); });
seastar::handle_signal(SIGINT, [this] { signaled(); });
seastar::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::handle_signal(SIGINT, [] {});
seastar::handle_signal(SIGTERM, [] {});
}
seastar::future<> wait() {
return _cond.wait([this] { return _caught; });
Expand Down
30 changes: 30 additions & 0 deletions doc/signal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Signals

Seastar provides an interface to handle signals natively and safely as asynchronous tasks.

It provides a dedicated header called [seastar/core/signal.hh](../include/seastar/core/signal.hh).

## Usage

You should call `seastar::handle_signal` procedure in order to register the provided signal handler for the specified signal based on the configuration params.

The procedure must be called inside the `app.run()` lambda, otherwise it's UB.

### Examples

```C++
#include <seastar/core/app-template.hh>
#include <seastar/core/signal.hh>

int main(int argc, char** argv) {
seastar::app_template app;
return app.run(argc, argv, [] {
seastar::handle_signal(SIGINT, [&] {
std::cout << "caught sigint\n";
}, true);
});
}
```
- [tests/unit/signal_test.cc](../tests/unit/signal_test.cc)
- [apps/lib/stop_signal.hh](../apps/lib/stop_signal.hh)
4 changes: 2 additions & 2 deletions include/seastar/core/app-template.hh
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public:
/// When false, Seastar will not set up signal handlers for SIGINT/SIGTERM
/// automatically. The default behavior (terminate the program) will be kept.
/// You can adjust the behavior of SIGINT/SIGTERM by installing signal handlers
/// via reactor::handle_signal().
/// via seastar::handle_signal(signo, handler, once); instead.
bool auto_handle_sigint_sigterm = true;
/// Specifies the default value for linux-aio I/O control blocks. This translates
/// to the maximum number of sockets the shard can handle.
Expand Down Expand Up @@ -104,7 +104,7 @@ public:
/// When false, Seastar will not set up signal handlers for SIGINT/SIGTERM
/// automatically. The default behavior (terminate the program) will be kept.
/// You can adjust the behavior of SIGINT/SIGTERM by installing signal handlers
/// via reactor::handle_signal().
/// via seastar::handle_signal(signo, handler, once); instead.
bool auto_handle_sigint_sigterm = true;
/// Configuration options for the reactor.
reactor_options reactor_opts;
Expand Down
3 changes: 3 additions & 0 deletions include/seastar/core/reactor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ private:
bool pure_poll_once();
public:
/// Register a user-defined signal handler
[[deprecated("Use seastar::handle_signal(signo, handler, once); instead")]]
void handle_signal(int signo, noncopyable_function<void ()>&& handler);
void wakeup();
/// @private
Expand Down Expand Up @@ -373,6 +374,8 @@ private:
friend class thread_context;
friend class internal::cpu_stall_detector;

friend void handle_signal(int signo, noncopyable_function<void ()>&& handler, bool once);

uint64_t pending_task_count() const;
void run_tasks(task_queue& tq);
bool have_more_tasks() const;
Expand Down
40 changes: 40 additions & 0 deletions include/seastar/core/signal.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.
*/

#pragma once

/// \file

// Seastar interface for POSIX signals.
#include <seastar/util/modules.hh>
#include <seastar/util/noncopyable_function.hh>

namespace seastar {

SEASTAR_MODULE_EXPORT_BEGIN

/// \brief Sets a signal handler for the specified signal.
///
/// \param signo Signal number.
/// \param handler Function to handle the signal.
/// \param once Should the handler be invoked only once.
void handle_signal(int signo, noncopyable_function<void ()>&& handler, bool once = false);

SEASTAR_MODULE_EXPORT_END

}
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ target_sources (seastar-module
core/sharded.cc
core/scollectd.cc
core/semaphore.cc
core/signal.cc
core/smp.cc
core/sstring.cc
core/systemwide_memory_barrier.cc
Expand Down
1 change: 1 addition & 0 deletions src/core/reactor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ module seastar;
#include <seastar/core/resource.hh>
#include <seastar/core/scheduling.hh>
#include <seastar/core/scheduling_specific.hh>
#include <seastar/core/signal.hh>
#include <seastar/core/sleep.hh>
#include <seastar/core/smp.hh>
#include <seastar/core/smp_options.hh>
Expand Down
43 changes: 43 additions & 0 deletions src/core/signal.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.
*/

#ifdef SEASTAR_MODULE
module;
#endif

#include <stdexcept>

#ifdef SEASTAR_MODULE
module seastar;
#else
#include <seastar/core/signal.hh>
#include <seastar/core/reactor.hh>
#endif

namespace seastar {

void handle_signal(int signo, noncopyable_function<void ()>&& handler, bool once) {
auto& r = engine();
if (once) {
r._signals.handle_signal_once(signo, std::move(handler));
} else {
r._signals.handle_signal(signo, std::move(handler));
}
}

}
1 change: 1 addition & 0 deletions src/seastar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export module seastar;
#include <seastar/core/shared_ptr.hh>
#include <seastar/core/shared_ptr_debug_helper.hh>
#include <seastar/core/shared_ptr_incomplete.hh>
#include <seastar/core/signal.hh>
#include <seastar/core/simple-stream.hh>
#include <seastar/core/sleep.hh>
#include <seastar/core/smp.hh>
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/signal_test.cc
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* Copyright (C) 2014 Cloudius Systems, Ltd.
*/

#include <seastar/core/reactor.hh>
#include <seastar/core/signal.hh>
#include <seastar/core/shared_ptr.hh>
#include <seastar/core/do_with.hh>
#include <seastar/testing/test_case.hh>
Expand All @@ -34,7 +34,7 @@ extern "C" {

SEASTAR_TEST_CASE(test_sighup) {
return do_with(make_lw_shared<promise<>>(), false, [](auto const& p, bool& signaled) {
engine().handle_signal(SIGHUP, [p, &signaled] {
seastar::handle_signal(SIGHUP, [p, &signaled] {
signaled = true;
p->set_value();
});
Expand Down

0 comments on commit c3e826a

Please sign in to comment.