summaryrefslogtreecommitdiff
path: root/lib/d
diff options
context:
space:
mode:
authorJames E. King III <jking@apache.org>2018-03-16 16:07:42 -0400
committerJames E. King III <jking@apache.org>2018-03-19 14:38:49 -0400
commit9bea32f73c36a8f53a45e818cfafe81b6fefefae (patch)
tree9598fe6b03c4b22d7baf84607bbabbbda1d66bc0 /lib/d
parent02fbe0ecc795881fe11a447d0a5f6f2f656f7bb4 (diff)
downloadthrift-9bea32f73c36a8f53a45e818cfafe81b6fefefae.tar.gz
THRIFT-4515: cross server test improvement: graceful test server shutdown
This closes #1509
Diffstat (limited to 'lib/d')
-rw-r--r--lib/d/test/thrift_test_server.d58
1 files changed, 55 insertions, 3 deletions
diff --git a/lib/d/test/thrift_test_server.d b/lib/d/test/thrift_test_server.d
index 71ab9175d..b582253c7 100644
--- a/lib/d/test/thrift_test_server.d
+++ b/lib/d/test/thrift_test_server.d
@@ -16,8 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
+
module thrift_test_server;
+import core.stdc.errno : errno;
+import core.stdc.signal : signal, sigfn_t, SIGINT, SIG_DFL, SIG_ERR;
import core.thread : dur, Thread;
import std.algorithm;
import std.exception : enforce;
@@ -40,6 +43,7 @@ import thrift.transport.buffered;
import thrift.transport.framed;
import thrift.transport.http;
import thrift.transport.ssl;
+import thrift.util.cancellation;
import thrift.util.hashset;
import test_utils;
@@ -205,14 +209,44 @@ private:
bool trace_;
}
+shared(bool) gShutdown = false;
+
+nothrow @nogc extern(C) void handleSignal(int sig) {
+ gShutdown = true;
+}
+
+// Runs a thread that waits for shutdown to be
+// signaled and then triggers cancellation,
+// causing the server to stop. While we could
+// use a signalfd for this purpose, we are instead
+// opting for a busy waiting scheme for maximum
+// portability since signalfd is a linux thing.
+
+class ShutdownThread : Thread {
+ this(TCancellationOrigin cancellation) {
+ cancellation_ = cancellation;
+ super(&run);
+ }
+
+private:
+ void run() {
+ while (!gShutdown) {
+ Thread.sleep(dur!("msecs")(25));
+ }
+ cancellation_.trigger();
+ }
+
+ TCancellationOrigin cancellation_;
+}
+
void main(string[] args) {
ushort port = 9090;
ServerType serverType;
ProtocolType protocolType;
size_t numIOThreads = 1;
TransportType transportType;
- bool ssl;
- bool trace;
+ bool ssl = false;
+ bool trace = true;
size_t taskPoolSize = totalCPUs;
getopt(args, "port", &port, "protocol", &protocolType, "server-type",
@@ -279,8 +313,26 @@ void main(string[] args) {
auto server = createServer(serverType, numIOThreads, taskPoolSize,
processor, serverSocket, transportFactory, protocolFactory);
+ // Set up SIGINT signal handling
+ sigfn_t oldHandler = signal(SIGINT, &handleSignal);
+ enforce(oldHandler != SIG_ERR,
+ "Could not replace the SIGINT signal handler: errno {0}".format(errno()));
+
+ // Set up a server cancellation trigger
+ auto cancel = new TCancellationOrigin();
+
+ // Set up a listener for the shutdown condition - this will
+ // wake up when the signal occurs and trigger cancellation.
+ auto shutdown = new ShutdownThread(cancel);
+ shutdown.start();
+
+ // Serve from this thread; the signal will stop the server
+ // and control will return here
writefln("Starting %s/%s %s ThriftTest server %son port %s...", protocolType,
transportType, serverType, ssl ? "(using SSL) ": "", port);
- server.serve();
+ server.serve(cancel);
+ shutdown.join();
+ signal(SIGINT, SIG_DFL);
+
writeln("done.");
}