/* grows the hashtable to the next power of 2. */ static void assoc_expand(struct default_engine *engine) { engine->assoc.old_hashtable = engine->assoc.primary_hashtable; engine->assoc.primary_hashtable = calloc(hashsize(engine->assoc.hashpower + 1), sizeof(hash_item *)); if (engine->assoc.primary_hashtable) { int ret = 0; cb_thread_t tid; engine->assoc.hashpower++; engine->assoc.expanding = true; engine->assoc.expand_bucket = 0; /* start a thread to do the expansion */ if ((ret = cb_create_thread(&tid, assoc_maintenance_thread, engine, 1)) != 0) { EXTENSION_LOGGER_DESCRIPTOR *logger; logger = (void*)engine->server.extension->get_extension(EXTENSION_LOGGER); logger->log(EXTENSION_LOG_WARNING, NULL, "Can't create thread: %s\n", strerror(ret)); engine->assoc.hashpower--; engine->assoc.expanding = false; free(engine->assoc.primary_hashtable); engine->assoc.primary_hashtable =engine->assoc.old_hashtable; } } else { engine->assoc.primary_hashtable = engine->assoc.old_hashtable; /* Bad news, but we can keep running. */ } }
/* * Make sure we can arithmetic operations to set the initial value of a key and * to then later increment that value */ static enum test_result mt_incr_test(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) { #define max_threads 30 cb_thread_t tid[max_threads]; item *test_item = NULL; void *key = "incr_test_key"; uint64_t cas = 0; uint64_t res = 0; int ii; if (max_threads < 2) { return SKIPPED; } cb_assert(h1->allocate(h, NULL, &test_item, key, strlen(key), 1, 0, 0, PROTOCOL_BINARY_RAW_BYTES) == ENGINE_SUCCESS); cb_assert(h1->arithmetic(h, NULL, key, (int)strlen(key), true, true, 0, 1, 0, &cas, PROTOCOL_BINARY_RAW_BYTES, &res, 0 ) == ENGINE_SUCCESS); h1->release(h, NULL, test_item); for (ii = 0; ii < max_threads; ++ii) { cb_assert(cb_create_thread(&tid[ii], incr_test_main, h, 0) == 0); } for (ii = 0; ii < max_threads; ++ii) { cb_assert(cb_join_thread(tid[ii]) == 0); } return SUCCESS; }
/* * Creates a worker thread. */ static void create_worker(void (*func)(void *), void *arg, cb_thread_t *id) { int ret; if ((ret = cb_create_thread(id, func, arg, 0)) != 0) { log_system_error(EXTENSION_LOG_WARNING, NULL, "Can't create thread: %s"); exit(1); } }
int stdin_check(void) { cb_thread_t t; if (cb_create_thread(&t, check_stdin_thread, NULL, 1) != 0) { perror("couldn't create stdin checking thread."); return -1; } return 0; }
int start_assoc_maintenance_thread() { int ret; char *env = getenv("MEMCACHED_HASH_BULK_MOVE"); if (env != NULL) { hash_bulk_move = atoi(env); if (hash_bulk_move == 0) { hash_bulk_move = DEFAULT_HASH_BULK_MOVE; } } if ((ret = cb_create_thread(&maintenance_tid, assoc_maintenance_thread, NULL, 0)) != 0) { moxi_log_write("Can't create thread: %s\n", strerror(ret)); return -1; } return 0; }