Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
@@ -22,13 +22,14 @@
22 22 #include <map>
23 23 #include <sstream>
24 24 #include <queue>
  25 +#include <list>
25 26 #include <cstring>
26 27 #include <cassert>
27 28 #include <cstdio>
28 29 #include <cstdlib>
29 30 #include <getopt.h>
30 31 #include "tools/commandlineparser.h"
31   -
  32 +#include <signal.h>
32 33
33 34 using namespace std;
34 35
@@ -210,6 +211,7 @@ class InstancePool
210 211 (void)lcb_set_store_callback(instance, storageCallback);
211 212 (void)lcb_set_get_callback(instance, getCallback);
212 213 queue.push(instance);
  214 + handles.push_back(instance);
213 215 } else {
214 216 std::cout << std::endl;
215 217 std::cerr << "Failed to create instance: "
@@ -235,9 +237,9 @@ class InstancePool
235 237 }
236 238
237 239 ~InstancePool() {
238   - while (!queue.empty()) {
239   - lcb_destroy(queue.front());
240   - queue.pop();
  240 + while (!handles.empty()) {
  241 + lcb_destroy(handles.back());
  242 + handles.pop_back();
241 243 }
242 244 }
243 245
@@ -265,6 +267,7 @@ class InstancePool
265 267
266 268 private:
267 269 std::queue<lcb_t> queue;
  270 + std::list<lcb_t> handles;
268 271 };
269 272
270 273
@@ -291,7 +294,10 @@ class ThreadContext
291 294 lcb_destroy_io_ops(io);
292 295 }
293 296
294   - bool run(bool loop) {
  297 + bool run() {
  298 + if (config.isLoop()) {
  299 + std::cerr << "Running in a loop. Press Ctrl-C to terminate..." << std::endl;
  300 + }
295 301 do {
296 302 bool pending = false;
297 303 lcb_t instance = pool->pop();
@@ -338,7 +344,7 @@ class ThreadContext
338 344
339 345 pool->push(instance);
340 346
341   - } while (loop);
  347 + } while (config.isLoop());
342 348
343 349 return true;
344 350 }
@@ -579,6 +585,36 @@ static void handle_options(int argc, char **argv)
579 585 }
580 586 }
581 587
  588 +ThreadContext *ctx = NULL;
  589 +
  590 +static void setup_sigint_handler(void (handler)(int));
  591 +static void cruel_handler(int);
  592 +static void gentle_handler(int);
  593 +
  594 +static void deaf_handler(int) { }
  595 +
  596 +static void cruel_handler(int)
  597 +{
  598 + delete ctx;
  599 + exit(EXIT_FAILURE);
  600 +}
  601 +
  602 +static void gentle_handler(int)
  603 +{
  604 + config.setLoop(false);
  605 + setup_sigint_handler(cruel_handler);
  606 +}
  607 +
  608 +static void setup_sigint_handler(void (handler)(int))
  609 +{
  610 + struct sigaction action;
  611 +
  612 + sigemptyset(&action.sa_mask);
  613 + action.sa_handler = handler;
  614 + action.sa_flags = 0;
  615 + sigaction(SIGINT, &action, NULL);
  616 +}
  617 +
582 618 /**
583 619 * Program entry point
584 620 * @param argc argument count
@@ -587,11 +623,14 @@ static void handle_options(int argc, char **argv)
587 623 */
588 624 int main(int argc, char **argv)
589 625 {
  626 + setup_sigint_handler(deaf_handler);
590 627 handle_options(argc, argv);
591 628
592   - ThreadContext ctx(config.getNumInstances());
593   - ctx.populate(0, config.maxKey);
594   - ctx.run(config.isLoop());
  629 + ctx = new ThreadContext(config.getNumInstances());
  630 + ctx->populate(0, config.maxKey);
  631 + setup_sigint_handler(gentle_handler);
  632 + ctx->run();
  633 + delete ctx;
595 634
596 635 return 0;
597 636 }
4 src/instance.c
@@ -990,9 +990,9 @@ static void vbucket_stream_handler(lcb_socket_t sock, short which, void *arg)
990 990 int sockerr = instance->io->v.v0.error;
991 991 if (sockerr != EWOULDBLOCK
992 992 #ifdef USE_EAGAIN
993   - && sockerr != EAGAIN
  993 + && sockerr != EAGAIN
994 994 #endif
995   - && sockerr != EINTR) {
  995 + && sockerr != EINTR) {
996 996 lcb_error_handler(instance, LCB_NETWORK_ERROR,
997 997 "Failed to send data to REST server");
998 998 instance->io->v.v0.delete_event(instance->io, instance->sock,
2  src/strerror.c
@@ -97,7 +97,7 @@ const char *lcb_strerror(lcb_t instance, lcb_error_t error)
97 97 " a version mismatch";
98 98 case LCB_INVALID_HOST_FORMAT:
99 99 return "One of the hostnames specified use invalid characters"
100   - " or an unsupported format";
  100 + " or an unsupported format";
101 101 default:
102 102 return "Unknown error.. are you sure libcouchbase gave you that?";
103 103 }

0 comments on commit 1364642

Please sign in to comment.
Something went wrong with that request. Please try again.