Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

pillowfight.cc: allow gracefully terminate the loop

The benefit of this changes is that pillowfight application won't mess
valgrdind output on premature termination because signal handler will
call destructor of ThreadContext

Change-Id: I3629d1df44f09f1c51ee1bb0da6897cacb81a67e
Reviewed-on: http://review.couchbase.org/25086
Tested-by: Sergey Avseyev <sergey.avseyev@gmail.com>
Reviewed-by: Trond Norbye <trond.norbye@gmail.com>
  • Loading branch information...
commit 13646424fe58b977fc6414de53e32c6f4633ba02 1 parent ecbb9fb
Sergey Avseyev avsej authored trondn committed
57 example/pillowfight/pillowfight.cc
View
@@ -22,13 +22,14 @@
#include <map>
#include <sstream>
#include <queue>
+#include <list>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <getopt.h>
#include "tools/commandlineparser.h"
-
+#include <signal.h>
using namespace std;
@@ -210,6 +211,7 @@ class InstancePool
(void)lcb_set_store_callback(instance, storageCallback);
(void)lcb_set_get_callback(instance, getCallback);
queue.push(instance);
+ handles.push_back(instance);
} else {
std::cout << std::endl;
std::cerr << "Failed to create instance: "
@@ -235,9 +237,9 @@ class InstancePool
}
~InstancePool() {
- while (!queue.empty()) {
- lcb_destroy(queue.front());
- queue.pop();
+ while (!handles.empty()) {
+ lcb_destroy(handles.back());
+ handles.pop_back();
}
}
@@ -265,6 +267,7 @@ class InstancePool
private:
std::queue<lcb_t> queue;
+ std::list<lcb_t> handles;
};
@@ -291,7 +294,10 @@ class ThreadContext
lcb_destroy_io_ops(io);
}
- bool run(bool loop) {
+ bool run() {
+ if (config.isLoop()) {
+ std::cerr << "Running in a loop. Press Ctrl-C to terminate..." << std::endl;
+ }
do {
bool pending = false;
lcb_t instance = pool->pop();
@@ -338,7 +344,7 @@ class ThreadContext
pool->push(instance);
- } while (loop);
+ } while (config.isLoop());
return true;
}
@@ -579,6 +585,36 @@ static void handle_options(int argc, char **argv)
}
}
+ThreadContext *ctx = NULL;
+
+static void setup_sigint_handler(void (handler)(int));
+static void cruel_handler(int);
+static void gentle_handler(int);
+
+static void deaf_handler(int) { }
+
+static void cruel_handler(int)
+{
+ delete ctx;
+ exit(EXIT_FAILURE);
+}
+
+static void gentle_handler(int)
+{
+ config.setLoop(false);
+ setup_sigint_handler(cruel_handler);
+}
+
+static void setup_sigint_handler(void (handler)(int))
+{
+ struct sigaction action;
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = handler;
+ action.sa_flags = 0;
+ sigaction(SIGINT, &action, NULL);
+}
+
/**
* Program entry point
* @param argc argument count
@@ -587,11 +623,14 @@ static void handle_options(int argc, char **argv)
*/
int main(int argc, char **argv)
{
+ setup_sigint_handler(deaf_handler);
handle_options(argc, argv);
- ThreadContext ctx(config.getNumInstances());
- ctx.populate(0, config.maxKey);
- ctx.run(config.isLoop());
+ ctx = new ThreadContext(config.getNumInstances());
+ ctx->populate(0, config.maxKey);
+ setup_sigint_handler(gentle_handler);
+ ctx->run();
+ delete ctx;
return 0;
}
4 src/instance.c
View
@@ -990,9 +990,9 @@ static void vbucket_stream_handler(lcb_socket_t sock, short which, void *arg)
int sockerr = instance->io->v.v0.error;
if (sockerr != EWOULDBLOCK
#ifdef USE_EAGAIN
- && sockerr != EAGAIN
+ && sockerr != EAGAIN
#endif
- && sockerr != EINTR) {
+ && sockerr != EINTR) {
lcb_error_handler(instance, LCB_NETWORK_ERROR,
"Failed to send data to REST server");
instance->io->v.v0.delete_event(instance->io, instance->sock,
2  src/strerror.c
View
@@ -97,7 +97,7 @@ const char *lcb_strerror(lcb_t instance, lcb_error_t error)
" a version mismatch";
case LCB_INVALID_HOST_FORMAT:
return "One of the hostnames specified use invalid characters"
- " or an unsupported format";
+ " or an unsupported format";
default:
return "Unknown error.. are you sure libcouchbase gave you that?";
}
Please sign in to comment.
Something went wrong with that request. Please try again.