/* This is a sanity check that watch/unwatch in a loop doesn't * leak matchtags. */ void test_unwatchloop (int argc, char **argv) { int i; flux_t *h; char *key; if (argc != 1) { fprintf (stderr, "Usage: unwatch key\n"); exit (1); } key = argv[0]; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); uint32_t avail = flux_matchtag_avail (h, 0); for (i = 0; i < 1000; i++) { if (kvs_watch_int (h, key, unwatchloop_cb, NULL) < 0) log_err_exit ("kvs_watch_int[%d] %s", i, key); if (kvs_unwatch (h, key) < 0) log_err_exit ("kvs_unwatch[%d] %s", i, key); } uint32_t leaked = avail - flux_matchtag_avail (h, 0); if (leaked > 0) log_msg_exit ("leaked %u matchtags", leaked); flux_close (h); }
static int unwatch_timer_cb (flux_t h, void *arg) { static int count = 0; const char *key = arg; if (kvs_put_int (h, key, count++) < 0) err_exit ("%s: kvs_put_int", __FUNCTION__); if (kvs_commit (h) < 0) err_exit ("%s: kvs_commit", __FUNCTION__); if (count == 10) { if (kvs_unwatch (h, key) < 0) err_exit ("%s: kvs_unwatch", __FUNCTION__); } else if (count == 20) flux_reactor_stop (flux_get_reactor (h)); return 0; }
static void unwatch_timer_cb (flux_reactor_t *r, flux_watcher_t *w, int revents, void *arg) { struct timer_ctx *ctx = arg; static int count = 0; log_msg ("%s", __FUNCTION__); if (kvs_put_int (ctx->h, ctx->key, count++) < 0) log_err_exit ("%s: kvs_put_int", __FUNCTION__); if (kvs_commit (ctx->h) < 0) log_err_exit ("%s: kvs_commit", __FUNCTION__); if (count == 10) { if (kvs_unwatch (ctx->h, ctx->key) < 0) log_err_exit ("%s: kvs_unwatch", __FUNCTION__); } else if (count == 20) flux_reactor_stop (r); }
void test_simulwatch (int argc, char **argv) { int i, max; const char *key; flux_t *h; int start, fin, count = 0; int exit_rc = 0; if (argc != 2) { fprintf (stderr, "Usage: simulwatch key count\n"); exit (1); } key = argv[0]; max = strtoul (argv[1], NULL, 10); if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (get_watch_stats (h, &start) < 0) log_err_exit ("kvs.stats.get"); for (i = 0; i < max; i++) { if (kvs_watch_int (h, key, simulwatch_cb, &count) < 0) log_err_exit ("kvs_watch_int[%d] %s", i, key); if ((i % 4096 == 0 && i > 0 && i + 4096 < max)) log_msg ("%d of %d watchers registered (continuing)", i, max); } log_msg ("%d of %d watchers registered", i, max); if (count != max) exit_rc = 1; log_msg ("callback called %d of %d times", count, max); if (get_watch_stats (h, &fin) < 0) log_err_exit ("kvs.stats.get"); if (fin - start != count) exit_rc = 1; log_msg ("%d of %d watchers running", fin - start, count); if (kvs_unwatch (h, key) < 0) log_err_exit ("kvs.unwatch"); if (get_watch_stats (h, &fin) < 0) log_err_exit ("kvs.stats.get"); if (fin - start != 0) exit_rc = 1; log_msg ("%d of %d watchers running after unwatch", fin - start, count); flux_close (h); if (exit_rc != 0) exit (exit_rc); }
int kz_close (kz_t *kz) { int rc = -1; char *json_str = NULL; char *key = NULL; if ((kz->flags & KZ_FLAGS_WRITE)) { if (!(kz->flags & KZ_FLAGS_RAW)) { if (asprintf (&key, "%s.%.6d", kz->name, kz->seq++) < 0) oom (); if (!(json_str = zio_json_encode (NULL, 0, true))) { /* EOF */ errno = EPROTO; goto done; } if (kvs_put (kz->h, key, json_str) < 0) goto done; } if (!(kz->flags & KZ_FLAGS_NOCOMMIT_CLOSE)) { if (kvs_commit (kz->h) < 0) goto done; } if (kz->nprocs > 0 && kz->grpname) { if (kz_fence (kz) < 0) goto done; } } if (kz->watching) { (void)kvs_unwatch (kz->h, kz->name); kz->watching = false; } rc = 0; done: if (json_str) free (json_str); if (key) free (key); kz_destroy (kz); return rc; }