int cmd_flush(int argc, char** argv, yrmcds* s) { uint32_t delay = 0; if( argc == 1 ) delay = (uint32_t)strtoull(argv[0], NULL, 0); yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_flush(s, delay, quiet, &serial); CHECK_ERROR(e); if( quiet ) { e = yrmcds_noop(s, &serial); CHECK_ERROR(e); } if( debug ) fprintf(stderr, "request serial = %u\n", serial); while( 1 ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); if( r->serial == serial ) break; } return 0; }
int cmd_unlock(int argc, char** argv, yrmcds* s) { if( argc != 1 ) { fprintf(stderr, "Wrong number of arguments.\n"); return 1; } yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_unlock(s, argv[0], strlen(argv[0]), quiet, &serial); CHECK_ERROR(e); if( quiet ) { e = yrmcds_noop(s, &serial); CHECK_ERROR(e); } if( debug ) fprintf(stderr, "request serial = %u\n", serial); while( 1 ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); if( r->serial == serial ) break; } return 0; }
int cmd_touch(int argc, char** argv, yrmcds* s) { if( argc != 2 ) { fprintf(stderr, "Wrong number of arguments.\n"); return 1; } const char* key = argv[0]; uint32_t expire = (uint32_t)strtoull(argv[1], NULL, 0); yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_touch(s, key, strlen(key), expire, quiet, &serial); CHECK_ERROR(e); if( quiet ) { e = yrmcds_noop(s, &serial); CHECK_ERROR(e); } if( debug ) fprintf(stderr, "request serial = %u\n", serial); while( 1 ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); if( r->serial == serial ) break; } return 0; }
int cmd_version(int argc, char** argv, yrmcds* s) { yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_version(s, &serial); CHECK_ERROR(e); e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); printf("%.*s\n", (int)r->data_len, r->data); return 0; }
int cmd_noop(int argc, char** argv, yrmcds* s) { yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_noop(s, &serial); CHECK_ERROR(e); if( debug ) fprintf(stderr, "request serial = %u\n", serial); e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); printf("OK\n"); return 0; }
int cmd_quit(int argc, char** argv, yrmcds* s) { yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_quit(s, quiet, &serial); CHECK_ERROR(e); if( debug ) fprintf(stderr, "request serial = %u\n", serial); if( ! quiet ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); } return 0; }
int cmd_add(int argc, char** argv, yrmcds* s) { if( argc < 2 || 5 < argc ) { fprintf(stderr, "Wrong number of arguments.\n"); return 1; } const char* key = argv[0]; char* data = NULL; size_t data_len = read_data(argv[1], &data); if( data == NULL ) { fprintf(stderr, "Failed to read data.\n"); return 2; } uint32_t expire = 0; uint32_t flags = 0; uint64_t cas = 0; if( argc > 2 ) expire = (uint32_t)strtoull(argv[2], NULL, 0); if( argc > 3 ) flags = (uint32_t)strtoull(argv[3], NULL, 0); if( argc > 4 ) cas = (uint64_t)strtoull(argv[4], NULL, 0); yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_add(s, key, strlen(key), data, data_len, flags, expire, cas, quiet, &serial); free(data); CHECK_ERROR(e); if( quiet ) { e = yrmcds_noop(s, &serial); CHECK_ERROR(e); } if( debug ) fprintf(stderr, "request serial = %u\n", serial); while( 1 ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); if( r->serial == serial ) break; } return 0; }
int cmd_decr(int argc, char** argv, yrmcds* s) { if( argc < 2 || 4 < argc ) { fprintf(stderr, "Wrong number of arguments.\n"); return 1; } const char* key = argv[0]; uint64_t value = (uint64_t)strtoull(argv[1], NULL, 0); uint64_t initial = 0; uint32_t expire = ~(uint32_t)0; if( argc > 2 ) { initial = (uint64_t)strtoull(argv[2], NULL, 0); expire = 0; } if( argc > 3 ) expire = (uint32_t)strtoull(argv[3], NULL, 0); yrmcds_response r[1]; uint32_t serial; yrmcds_error e; if( argc == 2 ) { e = yrmcds_decr(s, key, strlen(key), value, quiet, &serial); } else { e = yrmcds_decr2(s, key, strlen(key), value, initial, expire, quiet, &serial); } CHECK_ERROR(e); if( quiet ) { e = yrmcds_noop(s, &serial); CHECK_ERROR(e); } if( debug ) fprintf(stderr, "request serial = %u\n", serial); while( 1 ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); if( r->serial == serial ) break; } printf("%" PRIu64 "\n", r->value); return 0; }
static yrmcds_error check_persistent_connection(php_yrmcds_t* conn, yrmcds_status* status) { yrmcds_error e; *status = YRMCDS_STATUS_OK; e = yrmcds_set_timeout(&conn->res, 1); if( e != YRMCDS_OK ) return e; uint32_t serial; e = yrmcds_noop(&conn->res, &serial); if( e != YRMCDS_OK ) return e; yrmcds_response r; do { e = yrmcds_recv(&conn->res, &r); if( e != YRMCDS_OK ) return e; } while( r.serial != serial ); *status = r.status; if( *status != YRMCDS_STATUS_OK ) return e; return yrmcds_set_timeout(&conn->res, (int)YRMCDS_G(default_timeout)); }
int cmd_unlockall(int argc, char** argv, yrmcds* s) { yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_unlockall(s, quiet, &serial); CHECK_ERROR(e); if( quiet ) { e = yrmcds_noop(s, &serial); CHECK_ERROR(e); } if( debug ) fprintf(stderr, "request serial = %u\n", serial); while( 1 ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); if( r->serial == serial ) break; } return 0; }
int cmd_prepend(int argc, char** argv, yrmcds* s) { if( argc != 2 ) { fprintf(stderr, "Wrong number of arguments.\n"); return 1; } const char* key = argv[0]; char* data = NULL; size_t data_len = read_data(argv[1], &data); if( data == NULL ) { fprintf(stderr, "Failed to read data.\n"); return 2; } yrmcds_response r[1]; uint32_t serial; yrmcds_error e = yrmcds_prepend(s, key, strlen(key), data, data_len, quiet, &serial); free(data); CHECK_ERROR(e); if( quiet ) { e = yrmcds_noop(s, &serial); CHECK_ERROR(e); } if( debug ) fprintf(stderr, "request serial = %u\n", serial); while( 1 ) { e = yrmcds_recv(s, r); CHECK_ERROR(e); if( debug ) print_response(r); CHECK_RESPONSE(r); if( r->serial == serial ) break; } return 0; }
YRMCDS_METHOD(Client, recv) { yrmcds_client_object* obj = YRMCDS_CLIENT_OBJECT_P(getThis()); yrmcds_response r; CHECK_YRMCDS( yrmcds_recv(&obj->conn->res, &r) ); object_init_ex(return_value, ce_yrmcds_response); #define UPDATE_PROP_LONG(name, value) \ zend_update_property_long(ce_yrmcds_response, return_value, ZEND_STRL(name), (long)value) UPDATE_PROP_LONG("serial", r.serial); UPDATE_PROP_LONG("length", r.length); UPDATE_PROP_LONG("status", r.status); UPDATE_PROP_LONG("command", r.command); UPDATE_PROP_LONG("cas_unique", r.cas_unique); UPDATE_PROP_LONG("flags", r.flags); if( r.key_len > 0 ) zend_update_property_stringl(ce_yrmcds_response, return_value, ZEND_STRL("key"), r.key, r.key_len); if( r.data_len > 0 ) zend_update_property_stringl(ce_yrmcds_response, return_value, ZEND_STRL("data"), r.data, r.data_len); UPDATE_PROP_LONG("value", r.value); #undef UPDATE_PROP_LONG }
static void reader_main(h2o_memcached_context_t *ctx) { struct st_h2o_memcached_conn_t conn = {ctx, {}, PTHREAD_MUTEX_INITIALIZER, {&conn.inflight, &conn.inflight}, 0}; pthread_t writer_thread; yrmcds_response resp; yrmcds_error err; /* connect to server and start the writer thread */ connect_to_server(conn.ctx, &conn.yrmcds); pthread_create(&writer_thread, NULL, writer_main, &conn); pthread_mutex_lock(&conn.ctx->mutex); ++conn.ctx->num_threads_connected; pthread_mutex_unlock(&conn.ctx->mutex); /* receive data until an error occurs */ while (1) { if ((err = yrmcds_recv(&conn.yrmcds, &resp)) != YRMCDS_OK) { fprintf(stderr, "[lib/common/memcached.c] yrmcds_recv:%s\n", yrmcds_strerror(err)); break; } h2o_memcached_req_t *req = pop_inflight(&conn, resp.serial); if (req == NULL) { fprintf(stderr, "[lib/common/memcached.c] received unexpected serial\n"); break; } if (resp.status == YRMCDS_STATUS_OK) { req->data.get.value = h2o_iovec_init(h2o_mem_alloc(resp.data_len), resp.data_len); memcpy(req->data.get.value.base, resp.data, resp.data_len); h2o_mem_set_secure((void *)resp.data, 0, resp.data_len); } h2o_multithread_send_message(req->data.get.receiver, &req->data.get.message); } /* send error to all the reqs in-flight */ pthread_mutex_lock(&conn.mutex); while (!h2o_linklist_is_empty(&conn.inflight)) { h2o_memcached_req_t *req = H2O_STRUCT_FROM_MEMBER(h2o_memcached_req_t, inflight, conn.inflight.next); h2o_linklist_unlink(&req->inflight); assert(req->type == REQ_TYPE_GET); h2o_multithread_send_message(req->data.get.receiver, &req->data.get.message); } pthread_mutex_unlock(&conn.mutex); /* stop the writer thread */ __sync_add_and_fetch(&conn.writer_exit_requested, 1); pthread_mutex_lock(&conn.ctx->mutex); pthread_cond_broadcast(&conn.ctx->cond); pthread_mutex_unlock(&conn.ctx->mutex); pthread_join(writer_thread, NULL); /* decrement num_threads_connected, and discard all the pending requests if no connections are alive */ pthread_mutex_lock(&conn.ctx->mutex); if (--conn.ctx->num_threads_connected == 0) { while (!h2o_linklist_is_empty(&conn.ctx->pending)) { h2o_memcached_req_t *req = H2O_STRUCT_FROM_MEMBER(h2o_memcached_req_t, pending, conn.ctx->pending.next); h2o_linklist_unlink(&req->pending); discard_req(req); } } pthread_mutex_unlock(&conn.ctx->mutex); /* close the connection */ yrmcds_close(&conn.yrmcds); }