void test_selfmod (int argc, char **argv) { flux_t *h; char *key; if (argc != 1) { fprintf (stderr, "Usage: selfmod key\n"); exit (1); } key = argv[0]; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (kvs_put_int (h, key, -1) < 0) log_err_exit ("kvs_put_int"); if (kvs_commit (h) < 0) log_err_exit ("kvs_commit"); if (kvs_watch_int (h, key, selfmod_watch_cb, h) < 0) log_err_exit ("kvs_watch_int"); log_msg ("reactor: start"); flux_reactor_run (flux_get_reactor (h), 0); log_msg ("reactor: end"); flux_close (h); }
static int selfmod_watch_cb (const char *key, int val, void *arg, int errnum) { log_msg ("%s: value = %d errnum = %d", __FUNCTION__, val, errnum); flux_t *h = arg; if (kvs_put_int (h, key, val + 1) < 0) log_err_exit ("%s: kvs_put_int", __FUNCTION__); if (kvs_commit (h) < 0) log_err_exit ("%s: kvs_commit", __FUNCTION__); return (val == 0 ? -1 : 0); }
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_mt (int argc, char **argv) { thd_t *thd; int i, rc; flux_t *h; int errors = 0; if (argc != 3) { fprintf (stderr, "Usage: mt nthreads changes key\n"); exit (1); } nthreads = strtoul (argv[0], NULL, 10); changes = strtoul (argv[1], NULL, 10); key = argv[2]; thd = xzmalloc (sizeof (*thd) * nthreads); if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); /* Set initial value of 'key' to -1 */ if (kvs_put_int (h, key, -1) < 0) log_err_exit ("kvs_put_int %s", key); key_stable = xasprintf ("%s-stable", key); if (kvs_put_int (h, key_stable, 0) < 0) log_err_exit ("kvs_put_int %s", key); if (kvs_commit (h) < 0) log_err_exit ("kvs_commit"); for (i = 0; i < nthreads; i++) { thd[i].n = i; thd[i].last_val = -42; if ((rc = pthread_attr_init (&thd[i].attr))) log_errn (rc, "pthread_attr_init"); if ((rc = pthread_create (&thd[i].tid, &thd[i].attr, thread, &thd[i]))) log_errn (rc, "pthread_create"); } wait_ready (); for (i = 0; i < changes; i++) { if (kvs_put_int (h, key, i) < 0) log_err_exit ("kvs_put_int %s", key); if (kvs_commit (h) < 0) log_err_exit ("kvs_commit"); } /* Verify that callbacks were called the correct number of times. * The nil and stable callbacks will be called exactly once before the * reactor is started, then should never be called again. * Due to commit merging on the master, the changing callback may * miss intervening values but it shouldn't be called extra times. */ for (i = 0; i < nthreads; i++) { if ((rc = pthread_join (thd[i].tid, NULL))) log_errn (rc, "pthread_join"); if (thd[i].nil_count != 1) { log_msg ("%d: nil callback called %d times (expected one)", i, thd[i].nil_count); errors++; } if (thd[i].stable_count != 1) { log_msg ("%d: stable callback called %d times (expected one)", i, thd[i].stable_count); errors++; } if (thd[i].change_count > changes + 1) { log_msg ("%d: changing callback called %d times (expected <= %d)", i, thd[i].change_count, changes + 1); errors++; } } if (errors > 0) exit (1); free (thd); free (key_stable); flux_close (h); }