void lcbio_ctx_put(lcbio_CTX *ctx, const void *buf, unsigned nbuf) { lcbio__EASYRB *erb = ctx->output; if (!erb) { ctx->output = erb = calloc(1, sizeof(*ctx->output)); if (!erb) { lcbio_ctx_senderr(ctx, LCB_CLIENT_ENOMEM); return; } erb->parent = ctx; if (!ringbuffer_initialize(&erb->rb, nbuf)) { lcbio_ctx_senderr(ctx, LCB_CLIENT_ENOMEM); return; } } if (!ringbuffer_ensure_capacity(&erb->rb, nbuf)) { lcbio_ctx_senderr(ctx, LCB_CLIENT_ENOMEM); return; } ringbuffer_write(&erb->rb, buf, nbuf); }
ringbuffer_t* ringbuffer_allocate( unsigned int size ) { ringbuffer_t* buffer = memory_allocate( 0, sizeof( ringbuffer_t ) + size, 0, MEMORY_PERSISTENT ); ringbuffer_initialize( buffer, size ); return buffer; }
static int init_request(struct observe_st *reqinfo) { if (!ringbuffer_initialize(&reqinfo->body, 512)) { return 0; } reqinfo->allocated = 1; return 1; }
static int init_request(struct observe_st *req) { memset(&req->req, 0, sizeof(req->req)); if (!ringbuffer_initialize(&req->body, 512)) { return 0; } req->allocated = 1; return 1; }
int ringbuffer_ensure_alignment(ringbuffer_t *c) { #if defined(__hpux__) || defined(__hpux) || defined(__sparc__) || defined(__sparc) intptr_t addr = (intptr_t)c->read_head; if (addr % 8 != 0) { ringbuffer_t copy; if (ringbuffer_initialize(©, c->size) == 0 || ringbuffer_memcpy(©, c, ringbuffer_get_nbytes(c)) == -1) { return -1; } ringbuffer_destruct(c); *c = copy; } #else (void)c; #endif return 0; }
static lcb_error_t reset_buffer(ringbuffer_t **rb, lcb_size_t defsz) { if (*rb) { ringbuffer_reset(*rb); return LCB_SUCCESS; } *rb = calloc(1, sizeof(**rb)); if (*rb == NULL) { return LCB_CLIENT_ENOMEM; } if (!ringbuffer_initialize(*rb, defsz)) { return LCB_CLIENT_ENOMEM; } return LCB_SUCCESS; }
void ringbuffer_stream_initialize( stream_ringbuffer_t* stream, unsigned int buffer_size, uint64_t total_size ) { memset( stream, 0, sizeof( stream_ringbuffer_t ) ); stream_initialize( (stream_t*)stream, system_byteorder() ); stream->type = STREAMTYPE_RINGBUFFER; stream->sequential = 1; stream->path = string_format( "ringbuffer://0x%" PRIfixPTR, stream ); stream->mode = STREAM_OUT | STREAM_IN | STREAM_BINARY; ringbuffer_initialize( RINGBUFFER_FROM_STREAM( stream ), buffer_size ); semaphore_initialize( &stream->signal_read, 0 ); semaphore_initialize( &stream->signal_write, 0 ); stream->total_size = total_size; stream->vtable = &_ringbuffer_stream_vtable; }
LIBCOUCHBASE_API lcb_error_t lcb_create(lcb_t *instance, const struct lcb_create_st *options) { const char *host = NULL; const char *user = NULL; const char *passwd = NULL; const char *bucket = NULL; struct lcb_io_opt_st *io = NULL; struct lcb_create_st options_container; struct lcb_create_st2 *e_options = &options_container.v.v2; lcb_type_t type = LCB_TYPE_BUCKET; lcb_t obj; lcb_error_t err; lcb_settings *settings; err = normalize_options(&options_container, options); if (err != LCB_SUCCESS) { return err; } host = get_nonempty_string(e_options->host); user = get_nonempty_string(e_options->user); passwd = get_nonempty_string(e_options->passwd); bucket = get_nonempty_string(e_options->bucket); io = e_options->io; type = e_options->type; if (type == LCB_TYPE_CLUSTER && user == NULL && passwd == NULL) { return LCB_EINVAL; } if (host == NULL) { host = "localhost"; } if (bucket == NULL) { bucket = "default"; } /* Do not allow people use Administrator account for data access */ if (type == LCB_TYPE_BUCKET && user && strcmp(user, bucket) != 0) { return LCB_INVALID_USERNAME; } if ((obj = calloc(1, sizeof(*obj))) == NULL) { return LCB_CLIENT_ENOMEM; } obj->type = type; obj->compat.type = (lcb_compat_t)0xdead; if (io == NULL) { lcb_io_opt_t ops; if ((err = lcb_create_io_ops(&ops, NULL)) != LCB_SUCCESS) { /* You can't initialize the library without a io-handler! */ free(obj); return err; } io = ops; io->v.v0.need_cleanup = 1; } settings = &obj->settings; settings->randomize_bootstrap_nodes = 1; settings->bummer = 0; settings->io = io; obj->syncmode = LCB_ASYNCHRONOUS; settings->ipv6 = LCB_IPV6_DISABLED; settings->operation_timeout = LCB_DEFAULT_TIMEOUT; settings->config_timeout = LCB_DEFAULT_CONFIGURATION_TIMEOUT; settings->config_node_timeout = LCB_DEFAULT_NODECONFIG_TIMEOUT; settings->views_timeout = LCB_DEFAULT_VIEW_TIMEOUT; settings->rbufsize = LCB_DEFAULT_RBUFSIZE; settings->wbufsize = LCB_DEFAULT_WBUFSIZE; settings->durability_timeout = LCB_DEFAULT_DURABILITY_TIMEOUT; settings->durability_interval = LCB_DEFAULT_DURABILITY_INTERVAL; settings->http_timeout = LCB_DEFAULT_HTTP_TIMEOUT; settings->weird_things_threshold = LCB_DEFAULT_CONFIG_ERRORS_THRESHOLD; settings->weird_things_delay = LCB_DEFAULT_CONFIG_ERRORS_DELAY; settings->max_redir = LCB_DEFAULT_CONFIG_MAXIMUM_REDIRECTS; settings->grace_next_cycle = LCB_DEFAULT_CLCONFIG_GRACE_CYCLE; settings->grace_next_provider = LCB_DEFAULT_CLCONFIG_GRACE_NEXT; settings->bc_http_stream_time = LCB_DEFAULT_BC_HTTP_DISCONNTMO; settings->bucket = strdup(bucket); settings->logger = lcb_init_console_logger(); settings->iid = lcb_instance_index++; if (user) { settings->username = strdup(user); } else { settings->username = strdup(settings->bucket); } if (passwd) { settings->password = strdup(passwd); } lcb_initialize_packet_handlers(obj); obj->memd_sockpool = connmgr_create(settings, io); obj->memd_sockpool->max_idle = 1; obj->memd_sockpool->idle_timeout = 10000000; obj->confmon = lcb_confmon_create(settings); obj->usernodes = hostlist_create(); /** We might want to sanitize this a bit more later on.. */ if (strstr(host, "://") != NULL && strstr(host, "http://") == NULL) { lcb_destroy(obj); return LCB_INVALID_HOST_FORMAT; } err = hostlist_add_string(obj->usernodes, host, -1, LCB_CONFIG_HTTP_PORT); if (err != LCB_SUCCESS) { lcb_destroy(obj); return err; } err = lcb_init_providers(obj, e_options); if (err != LCB_SUCCESS) { lcb_destroy(obj); return err; } lcb_initialize_packet_handlers(obj); obj->timers = hashset_create(); obj->http_requests = hashset_create(); obj->durability_polls = hashset_create(); /* No error has occurred yet. */ obj->last_error = LCB_SUCCESS; if ((obj->cmdht = lcb_hashtable_szt_new(32)) == NULL) { lcb_destroy(obj); return LCB_CLIENT_ENOMEM; } if (!ringbuffer_initialize(&obj->purged_buf, 4096)) { lcb_destroy(obj); return LCB_CLIENT_ENOMEM; } if (!ringbuffer_initialize(&obj->purged_cookies, 4096)) { lcb_destroy(obj); return LCB_CLIENT_ENOMEM; } *instance = obj; return LCB_SUCCESS; }
static void purge_single_server(lcb_server_t *server, lcb_error_t error, hrtime_t min_nonstale, hrtime_t *tmo_next) { protocol_binary_request_header req; struct lcb_command_data_st ct; lcb_size_t nr; char *packet; lcb_size_t packetsize; char *keyptr; ringbuffer_t rest; ringbuffer_t *stream = &server->cmd_log; ringbuffer_t *cookies; ringbuffer_t *mirror = NULL; /* mirror buffer should be purged with main stream */ lcb_connection_t conn = &server->connection; lcb_size_t send_size = 0; lcb_size_t stream_size = ringbuffer_get_nbytes(stream); hrtime_t now = gethrtime(); if (server->connection_ready) { cookies = &server->output_cookies; } else { cookies = &server->pending_cookies; mirror = &server->pending; } if (conn->output) { /* This will usually be false for v1 */ send_size = ringbuffer_get_nbytes(conn->output); } lcb_assert(ringbuffer_initialize(&rest, 1024)); do { int allocated = 0; lcb_uint32_t headersize; lcb_uint16_t nkey; nr = ringbuffer_peek(cookies, &ct, sizeof(ct)); if (nr != sizeof(ct)) { break; } nr = ringbuffer_peek(stream, req.bytes, sizeof(req)); if (nr != sizeof(req)) { break; } packetsize = (lcb_uint32_t)sizeof(req) + ntohl(req.request.bodylen); if (stream->nbytes < packetsize) { break; } if (min_nonstale && ct.start >= min_nonstale) { lcb_log(LOGARGS(server, INFO), "Still have %d ms remaining for command", (ct.start - min_nonstale) / 1000000); if (tmo_next) { *tmo_next = (ct.start - min_nonstale) + 1; } break; } lcb_log(LOGARGS(server, INFO), "Command with cookie=%p timed out from server %s:%s", ct.cookie, server->curhost.host, server->curhost.port); ringbuffer_consumed(cookies, sizeof(ct)); lcb_assert(nr == sizeof(req)); packet = stream->read_head; if (server->instance->histogram) { lcb_record_metrics(server->instance, now - ct.start, req.request.opcode); } if (server->connection_ready && stream_size > send_size && (stream_size - packetsize) < send_size) { /* Copy the rest of the current packet into the temporary stream */ /* I do believe I have some IOV functions to do that? */ lcb_size_t nbytes = packetsize - (stream_size - send_size); lcb_assert(ringbuffer_memcpy(&rest, conn->output, nbytes) == 0); ringbuffer_consumed(conn->output, nbytes); send_size -= nbytes; } stream_size -= packetsize; headersize = (lcb_uint32_t)sizeof(req) + req.request.extlen + htons(req.request.keylen); if (!ringbuffer_is_continous(stream, RINGBUFFER_READ, headersize)) { packet = malloc(headersize); if (packet == NULL) { lcb_error_handler(server->instance, LCB_CLIENT_ENOMEM, NULL); abort(); } nr = ringbuffer_peek(stream, packet, headersize); if (nr != headersize) { lcb_error_handler(server->instance, LCB_EINTERNAL, NULL); free(packet); abort(); } allocated = 1; } keyptr = packet + sizeof(req) + req.request.extlen; nkey = ntohs(req.request.keylen); failout_single_request(server, &req, &ct, error, keyptr, nkey, packet); if (allocated) { free(packet); } ringbuffer_consumed(stream, packetsize); if (mirror) { ringbuffer_consumed(mirror, packetsize); } } while (1); /* CONSTCOND */ if (server->connection_ready && conn->output) { /* Preserve the rest of the stream */ lcb_size_t nbytes = ringbuffer_get_nbytes(stream); send_size = ringbuffer_get_nbytes(conn->output); if (send_size >= nbytes) { ringbuffer_consumed(conn->output, send_size - nbytes); lcb_assert(ringbuffer_memcpy(&rest, conn->output, nbytes) == 0); } ringbuffer_reset(conn->output); ringbuffer_append(&rest, conn->output); } ringbuffer_destruct(&rest); lcb_maybe_breakout(server->instance); }
static libcouchbase_error_t create_memcached(const struct libcouchbase_memcached_st *user, VBUCKET_CONFIG_HANDLE vbconfig) { ringbuffer_t buffer; char *copy = strdup(user->serverlist); char head[1024]; int first; char *ptr = copy; int fail; libcouchbase_ssize_t offset = 0; if (copy == NULL) { return LIBCOUCHBASE_CLIENT_ENOMEM; } if (ringbuffer_initialize(&buffer, 1024) == -1) { free(copy); return LIBCOUCHBASE_CLIENT_ENOMEM; } head[0] = '\0'; offset += snprintf(head + offset, sizeof(head) - offset, "%s", "{"); offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\"bucketType\":\"memcached\","); offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\"nodeLocator\":\"ketama\","); if (user->username != NULL) { offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\"authType\":\"sasl\","); offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\"name\":\""); offset += snprintf(head + offset, sizeof(head) - offset, "%s", user->username); offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\","); if (user->password != NULL) { offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\"saslPassword\":\""); offset += snprintf(head + offset, sizeof(head) - offset, "%s", user->password); offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\","); } } offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\"nodes\": ["); ringbuffer_write(&buffer, head, strlen(head)); /* Let's add the hosts... */ first = 1; do { char *tok; char *next = strchr(ptr, ';'); const char *port = "11211"; libcouchbase_ssize_t length; if (next != NULL) { *next = '\0'; } tok = strchr(ptr, ':'); if (tok != NULL) { *tok = '\0'; port = tok + 1; if ((tok = strchr(ptr, ':')) != NULL) { *tok = '\0'; /* Remove weight for now */ } } length = snprintf(head, sizeof(head), "%c{\"hostname\":\"%s\",\"ports\":{\"direct\":%s}}", first ? ' ' : ',', ptr, port); first = 0; if (ringbuffer_ensure_capacity(&buffer, length) == -1) { free(copy); return LIBCOUCHBASE_CLIENT_ENOMEM; } ringbuffer_write(&buffer, head, length); if (next != NULL) { ptr = next + 1; } else { ptr = NULL; } } while (ptr != NULL); if (ringbuffer_ensure_capacity(&buffer, 3) == -1) { free(copy); return LIBCOUCHBASE_CLIENT_ENOMEM; } ringbuffer_write(&buffer, "]}", 3); /* Include '\0' */ /* Now let's parse the config! */ fail = vbucket_config_parse(vbconfig, LIBVBUCKET_SOURCE_MEMORY, (char *)ringbuffer_get_read_head(&buffer)); free(copy); ringbuffer_destruct(&buffer); if (fail) { /* Hmm... internal error! */ return LIBCOUCHBASE_EINTERNAL; } return LIBCOUCHBASE_SUCCESS; }