void
cb_http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp)
{
    struct cb_context_st *ctx = (struct cb_context_st *)cookie;
    struct cb_bucket_st *bucket = ctx->bucket;
    VALUE key, val, res, exc;
    lcb_http_status_t status;

    ctx->request->completed = 1;

    if (bucket->destroying) {
        cb_context_free(ctx);
        return;
    }

    key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
    val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
    exc = ctx->exception;
    if (!RTEST(exc)) {
        exc = cb_check_error_with_status(error, "failed to execute HTTP request", key, resp->v.v0.status);
        if (exc != Qnil && val != Qnil) {
            rb_ivar_set(exc, cb_id_iv_body, val);
        }
    }
    if (RTEST(exc)) {
        if (rb_obj_is_kind_of(exc, cb_eHTTPError)) {
            rb_funcall(exc, cb_id_parse_body_bang, 0);
        }
        ctx->exception = exc;
    }
    status = resp->v.v0.status;
    if (resp->v.v0.headers) {
        cb_build_headers(ctx, resp->v.v0.headers);
        ctx->headers_val = Qnil;
    }
    if (ctx->extended) {
        res = rb_class_new_instance(0, NULL, cb_cResult);
        rb_ivar_set(res, cb_id_iv_error, ctx->exception);
        rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
        rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request);
        rb_ivar_set(res, cb_id_iv_key, key);
        rb_ivar_set(res, cb_id_iv_value, val);
        rb_ivar_set(res, cb_id_iv_completed, Qtrue);
        rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val);
    } else {
        res = val;
    }
    if (ctx->proc != Qnil) {
        cb_proc_call(bucket, ctx->proc, 1, res);
        ctx->proc = Qnil;
    }
    if (!bucket->async && ctx->exception == Qnil) {
        ctx->rv = res;
    }
    if (bucket->async) {
        cb_context_free(ctx);
    }
    (void)handle;
    (void)request;
}
    void
http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp)
{
    struct context_st *ctx = (struct context_st *)cookie;
    struct bucket_st *bucket = ctx->bucket;
    VALUE key, val, res;

    key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
    ctx->exception = cb_check_error_with_status(error,
            "failed to execute HTTP request", key, resp->v.v0.status);
    val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
    if (ctx->exception != Qnil) {
        cb_gc_protect(bucket, ctx->exception);
        lcb_cancel_http_request(bucket->handle, request);
    }
    if (resp->v.v0.headers) {
        cb_build_headers(ctx, resp->v.v0.headers);
    }
    if (ctx->proc != Qnil) {
        if (ctx->extended) {
            res = rb_class_new_instance(0, NULL, cResult);
            rb_ivar_set(res, id_iv_error, ctx->exception);
            rb_ivar_set(res, id_iv_operation, sym_http_request);
            rb_ivar_set(res, id_iv_key, key);
            rb_ivar_set(res, id_iv_value, val);
            rb_ivar_set(res, id_iv_completed, Qfalse);
            rb_ivar_set(res, id_iv_headers, ctx->headers_val);
        } else {
            res = val;
        }
        cb_proc_call(ctx->proc, 1, res);
    }
    (void)handle;
}
    void
observe_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_observe_resp_t *resp)
{
    struct context_st *ctx = (struct context_st *)cookie;
    struct bucket_st *bucket = ctx->bucket;
    VALUE key, res, *rv = ctx->rv;

    if (resp->v.v0.key) {
        key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
        ctx->exception = cb_check_error(error, "failed to execute observe request", key);
        if (ctx->exception) {
            cb_gc_protect(bucket, ctx->exception);
        }
        res = rb_class_new_instance(0, NULL, cResult);
        rb_ivar_set(res, id_iv_completed, Qfalse);
        rb_ivar_set(res, id_iv_error, ctx->exception);
        rb_ivar_set(res, id_iv_operation, sym_observe);
        rb_ivar_set(res, id_iv_key, key);
        rb_ivar_set(res, id_iv_cas, ULL2NUM(resp->v.v0.cas));
        rb_ivar_set(res, id_iv_from_master, resp->v.v0.from_master ? Qtrue : Qfalse);
        rb_ivar_set(res, id_iv_time_to_persist, ULONG2NUM(resp->v.v0.ttp));
        rb_ivar_set(res, id_iv_time_to_replicate, ULONG2NUM(resp->v.v0.ttr));
        switch (resp->v.v0.status) {
            case LCB_OBSERVE_FOUND:
                rb_ivar_set(res, id_iv_status, sym_found);
                break;
            case LCB_OBSERVE_PERSISTED:
                rb_ivar_set(res, id_iv_status, sym_persisted);
                break;
            case LCB_OBSERVE_NOT_FOUND:
                rb_ivar_set(res, id_iv_status, sym_not_found);
                break;
            default:
                rb_ivar_set(res, id_iv_status, Qnil);
        }
        if (bucket->async) { /* asynchronous */
            if (ctx->proc != Qnil) {
                cb_proc_call(ctx->proc, 1, res);
            }
        } else {             /* synchronous */
            if (NIL_P(ctx->exception)) {
                VALUE stats = rb_hash_aref(*rv, key);
                if (NIL_P(stats)) {
                    stats = rb_ary_new();
                    rb_hash_aset(*rv, key, stats);
                }
                rb_ary_push(stats, res);
            }
        }
    } else {
        if (bucket->async && ctx->proc != Qnil) {
            res = rb_class_new_instance(0, NULL, cResult);
            rb_ivar_set(res, id_iv_completed, Qtrue);
            cb_proc_call(ctx->proc, 1, res);
        }
        ctx->nqueries--;
        cb_gc_unprotect(bucket, ctx->proc);
    }
    (void)handle;
}
void
cb_http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp)
{
    struct cb_context_st *ctx = (struct cb_context_st *)cookie;
    struct cb_bucket_st *bucket = ctx->bucket;
    VALUE key, val, res;
    lcb_http_status_t status;

    key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath);
    val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil;
    status = resp->v.v0.status;
    if (NIL_P(ctx->exception)) {
        ctx->exception = cb_check_error_with_status(error,
                         "failed to execute HTTP request", key, resp->v.v0.status);
        if (ctx->exception != Qnil) {
            VALUE body_str = rb_ivar_get(ctx->exception, cb_id_iv_body);
            if (NIL_P(body_str)) {
                rb_ivar_set(ctx->exception, cb_id_iv_body, val);
            } else {
                rb_str_concat(body_str, val);
            }
            return;
        }
    }
    if (resp->v.v0.headers) {
        cb_build_headers(ctx, resp->v.v0.headers);
    }
    if (ctx->proc != Qnil) {
        if (ctx->extended) {
            res = rb_class_new_instance(0, NULL, cb_cResult);
            rb_ivar_set(res, cb_id_iv_error, Qnil);
            rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
            rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request);
            rb_ivar_set(res, cb_id_iv_key, key);
            rb_ivar_set(res, cb_id_iv_value, val);
            rb_ivar_set(res, cb_id_iv_completed, Qfalse);
            rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val);
        } else {
            res = val;
        }
        cb_proc_call(bucket, ctx->proc, 1, res);
    }
    (void)handle;
}
    void
arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_arithmetic_resp_t *resp)
{
    struct context_st *ctx = (struct context_st *)cookie;
    struct bucket_st *bucket = ctx->bucket;
    VALUE cas, key, val, *rv = ctx->rv, exc, res;
    ID o;

    ctx->nqueries--;
    key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
    strip_key_prefix(bucket, key);

    cas = resp->v.v0.cas > 0 ? ULL2NUM(resp->v.v0.cas) : Qnil;
    o = ctx->arith > 0 ? sym_increment : sym_decrement;
    exc = cb_check_error(error, "failed to perform arithmetic operation", key);
    if (exc != Qnil) {
        rb_ivar_set(exc, id_iv_cas, cas);
        rb_ivar_set(exc, id_iv_operation, o);
        if (bucket->async) {
            if (bucket->on_error_proc != Qnil) {
                cb_proc_call(bucket->on_error_proc, 3, o, key, exc);
            } else {
                if (NIL_P(bucket->exception)) {
                    bucket->exception = exc;
                }
            }
        }
        if (NIL_P(ctx->exception)) {
            ctx->exception = cb_gc_protect(bucket, exc);
        }
    }
    val = ULL2NUM(resp->v.v0.value);
    if (bucket->async) {    /* asynchronous */
        if (ctx->proc != Qnil) {
            res = rb_class_new_instance(0, NULL, cResult);
            rb_ivar_set(res, id_iv_error, exc);
            rb_ivar_set(res, id_iv_operation, o);
            rb_ivar_set(res, id_iv_key, key);
            rb_ivar_set(res, id_iv_value, val);
            rb_ivar_set(res, id_iv_cas, cas);
            cb_proc_call(ctx->proc, 1, res);
        }
    } else {                /* synchronous */
        if (NIL_P(exc)) {
            if (ctx->extended) {
                rb_hash_aset(*rv, key, rb_ary_new3(2, val, cas));
            } else {
                rb_hash_aset(*rv, key, val);
            }
        }
    }
    if (ctx->nqueries == 0) {
        cb_gc_unprotect(bucket, ctx->proc);
    }
    (void)handle;
}
Exemple #6
0
    void
cb_storage_callback(lcb_t handle, const void *cookie, lcb_storage_t operation,
        lcb_error_t error, const lcb_store_resp_t *resp)
{
    struct cb_context_st *ctx = (struct cb_context_st *)cookie;
    struct cb_bucket_st *bucket = ctx->bucket;
    VALUE key, cas, exc, res;

    key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
    cb_strip_key_prefix(bucket, key);

    cas = resp->v.v0.cas > 0 ? ULL2NUM(resp->v.v0.cas) : Qnil;
    ctx->operation = storage_opcode_to_sym(operation);
    exc = cb_check_error(error, "failed to store value", key);
    if (exc != Qnil) {
        rb_ivar_set(exc, cb_id_iv_cas, cas);
        rb_ivar_set(exc, cb_id_iv_operation, ctx->operation);
        ctx->exception = exc;
    }

    if (bucket->async) { /* asynchronous */
        if (RTEST(ctx->observe_options)) {
            VALUE args[2]; /* it's ok to pass pointer to stack struct here */
            args[0] = rb_hash_new();
            rb_hash_aset(args[0], key, cas);
            args[1] = ctx->observe_options;
            rb_block_call(bucket->self, cb_id_observe_and_wait, 2, args,
                    storage_observe_callback, (VALUE)ctx);
            ctx->observe_options = Qnil;
        } else if (ctx->proc != Qnil) {
            res = rb_class_new_instance(0, NULL, cb_cResult);
            rb_ivar_set(res, cb_id_iv_error, exc);
            rb_ivar_set(res, cb_id_iv_key, key);
            rb_ivar_set(res, cb_id_iv_operation, ctx->operation);
            rb_ivar_set(res, cb_id_iv_cas, cas);
            cb_proc_call(bucket, ctx->proc, 1, res);
        }
    } else {             /* synchronous */
        rb_hash_aset(ctx->rv, key, cas);
    }

    if (!RTEST(ctx->observe_options)) {
        ctx->nqueries--;
        if (ctx->nqueries == 0) {
            ctx->proc = Qnil;
            if (bucket->async) {
                cb_context_free(ctx);
            }
        }
    }
    (void)handle;
}
static VALUE elements_to_hash(const char* buffer, int max) {
    VALUE hash = rb_class_new_instance(0, NULL, OrderedHash);
    int position = 0;
    while (position < max) {
        int type = (int)buffer[position++];
        int name_length = (int)strlen(buffer + position);
        VALUE name = STR_NEW(buffer + position, name_length);
        VALUE value;
        position += name_length + 1;
        value = get_value(buffer, &position, type);
        rb_funcall(hash, element_assignment_method, 2, name, value);
    }
    return hash;
}
/*
 * Execute {Bucket::CouchRequest}
 *
 * @since 1.2.0
 */
    VALUE
cb_http_request_perform(VALUE self)
{
    struct http_request_st *req = DATA_PTR(self);
    struct context_st *ctx;
    VALUE rv, exc;
    lcb_error_t err;
    struct bucket_st *bucket;

    ctx = xcalloc(1, sizeof(struct context_st));
    if (ctx == NULL) {
        rb_raise(eClientNoMemoryError, "failed to allocate memory");
    }
    rv = Qnil;
    ctx->rv = &rv;
    ctx->bucket = bucket = req->bucket;
    ctx->proc = rb_block_given_p() ? rb_block_proc() : req->on_body_callback;
    ctx->extended = req->extended;
    ctx->request = req;
    ctx->headers_val = cb_gc_protect(bucket, rb_hash_new());

    err = lcb_make_http_request(bucket->handle, (const void *)ctx,
            req->type, &req->cmd, &req->request);
    exc = cb_check_error(err, "failed to schedule document request",
            STR_NEW(req->cmd.v.v0.path, req->cmd.v.v0.npath));
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    req->running = 1;
    req->ctx = ctx;
    if (bucket->async) {
        return Qnil;
    } else {
        lcb_wait(bucket->handle);
        if (req->completed) {
            exc = ctx->exception;
            xfree(ctx);
            if (exc != Qnil) {
                cb_gc_unprotect(bucket, exc);
                rb_exc_raise(exc);
            }
            return rv;
        } else {
            return Qnil;
        }
    }
    return Qnil;
}
/*
 * Execute {Bucket::CouchRequest}
 *
 * @since 1.2.0
 */
VALUE
cb_http_request_perform(VALUE self)
{
    struct cb_http_request_st *req = DATA_PTR(self);
    struct cb_context_st *ctx;
    VALUE rv, exc;
    lcb_error_t err;
    struct cb_bucket_st *bucket = req->bucket;

    if (bucket->handle == NULL) {
        rb_raise(cb_eConnectError, "closed connection");
    }

    ctx = cb_context_alloc(bucket);
    ctx->rv = Qnil;
    ctx->proc = rb_block_given_p() ? rb_block_proc() : req->on_body_callback;
    ctx->extended = req->extended;
    ctx->request = req;
    ctx->headers_val = rb_hash_new();

    err = lcb_make_http_request(bucket->handle, (const void *)ctx,
                                req->type, &req->cmd, &req->request);
    exc = cb_check_error(err, "failed to schedule document request",
                         STR_NEW(req->cmd.v.v0.path, req->cmd.v.v0.npath));
    if (exc != Qnil) {
        lcb_cancel_http_request(bucket->handle, req->request);
        rb_exc_raise(exc);
    }
    req->running = 1;
    req->ctx = ctx;
    if (bucket->async) {
        return Qnil;
    } else {
        lcb_wait(bucket->handle);
        if (req->completed) {
            rv = ctx->rv;
            exc = ctx->exception;
            cb_context_free(ctx);
            if (exc != Qnil) {
                rb_exc_raise(exc);
            }
            return rv;
        } else {
            return Qnil;
        }
    }
    return Qnil;
}
    void
cb_version_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_server_version_resp_t *resp)
{
    struct cb_context_st *ctx = (struct cb_context_st *)cookie;
    struct cb_bucket_st *bucket = ctx->bucket;
    VALUE node, val, exc, res;

    node = resp->v.v0.server_endpoint ? STR_NEW_CSTR(resp->v.v0.server_endpoint) : Qnil;
    exc = cb_check_error(error, "failed to get version", node);
    if (exc != Qnil) {
        rb_ivar_set(exc, cb_id_iv_operation, cb_sym_version);
        ctx->exception = exc;
    }

    if (node != Qnil) {
        val = STR_NEW((const char*)resp->v.v0.vstring, resp->v.v0.nvstring);
        if (bucket->async) {    /* asynchronous */
            if (ctx->proc != Qnil) {
                res = rb_class_new_instance(0, NULL, cb_cResult);
                rb_ivar_set(res, cb_id_iv_error, exc);
                rb_ivar_set(res, cb_id_iv_operation, cb_sym_version);
                rb_ivar_set(res, cb_id_iv_node, node);
                rb_ivar_set(res, cb_id_iv_value, val);
                cb_proc_call(bucket, ctx->proc, 1, res);
            }
        } else {                /* synchronous */
            if (NIL_P(exc)) {
                rb_hash_aset(ctx->rv, node, val);
            }
        }
    } else {
        ctx->nqueries--;
        ctx->proc = Qnil;
        if (bucket->async) {
            cb_context_free(ctx);
        }
    }

    (void)handle;
}
Exemple #11
0
static VALUE elements_to_hash(const char* buffer, int max, int symbolize_keys) {
    VALUE hash = rb_class_new_instance(0, NULL, OrderedHash);
    int position = 0;
    while (position < max) {
        int type = (int)buffer[position++];
        int name_length = strlen(buffer + position);
        VALUE name;
        if (symbolize_keys) {
            char buf[name_length+1];
            memcpy(buf, buffer + position, name_length);
            buf[name_length] = 0;
            name = ID2SYM(rb_intern(buf));
        } else {
            name = STR_NEW(buffer + position, name_length);
        }
        VALUE value;
        position += name_length + 1;
        value = get_value(buffer, &position, type);
        rb_funcall(hash, rb_intern("[]="), 2, name, value);
    }
    return hash;
}
    void
cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_unlock_resp_t *resp)
{
    struct cb_context_st *ctx = (struct cb_context_st *)cookie;
    struct cb_bucket_st *bucket = ctx->bucket;
    VALUE key, exc = Qnil, res;

    ctx->nqueries--;
    key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
    cb_strip_key_prefix(bucket, key);

    if (error != LCB_KEY_ENOENT || !ctx->quiet) {
        exc = cb_check_error(error, "failed to unlock value", key);
        if (exc != Qnil) {
            rb_ivar_set(exc, cb_id_iv_operation, cb_sym_unlock);
            ctx->exception = exc;
        }
    }

    if (bucket->async) {    /* asynchronous */
        if (ctx->proc != Qnil) {
            res = rb_class_new_instance(0, NULL, cb_cResult);
            rb_ivar_set(res, cb_id_iv_error, exc);
            rb_ivar_set(res, cb_id_iv_operation, cb_sym_unlock);
            rb_ivar_set(res, cb_id_iv_key, key);
            cb_proc_call(bucket, ctx->proc, 1, res);
        }
    } else {                /* synchronous */
        rb_hash_aset(ctx->rv, key, (error == LCB_SUCCESS) ? Qtrue : Qfalse);
    }
    if (ctx->nqueries == 0) {
        ctx->proc = Qnil;
        if (bucket->async) {
            cb_context_free(ctx);
        }
    }
    (void)handle;
}
Exemple #13
0
static VALUE get_value(const char* buffer, int* position, int type) {
    VALUE value;
    switch (type) {
    case -1:
        {
            value = rb_class_new_instance(0, NULL, MinKey);
            break;
        }
    case 1:
        {
            double d;
            memcpy(&d, buffer + *position, 8);
            value = rb_float_new(d);
            *position += 8;
            break;
        }
    case 2:
    case 13:
        {
            int value_length;
            value_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            value = STR_NEW(buffer + *position, value_length);
            *position += value_length + 1;
            break;
        }
    case 3:
        {
            int size;
            memcpy(&size, buffer + *position, 4);
            if (strcmp(buffer + *position + 5, "$ref") == 0) { // DBRef
                int offset = *position + 10;
                VALUE argv[2];
                int collection_length = *(int*)(buffer + offset) - 1;
                char id_type;
                offset += 4;

                argv[0] = STR_NEW(buffer + offset, collection_length);
                offset += collection_length + 1;
                id_type = buffer[offset];
                offset += 5;
                argv[1] = get_value(buffer, &offset, (int)id_type);
                value = rb_class_new_instance(2, argv, DBRef);
            } else {
                value = elements_to_hash(buffer + *position + 4, size - 5);
            }
            *position += size;
            break;
        }
    case 4:
        {
            int size, end;
            memcpy(&size, buffer + *position, 4);
            end = *position + size - 1;
            *position += 4;

            value = rb_ary_new();
            while (*position < end) {
                int type = (int)buffer[(*position)++];
                int key_size = (int)strlen(buffer + *position);
                VALUE to_append;

                *position += key_size + 1; // just skip the key, they're in order.
                to_append = get_value(buffer, position, type);
                rb_ary_push(value, to_append);
            }
            (*position)++;
            break;
        }
    case 5:
        {
            int length, subtype;
            VALUE data, st;
            VALUE argv[2];
            memcpy(&length, buffer + *position, 4);
            subtype = (unsigned char)buffer[*position + 4];
            if (subtype == 2) {
                data = rb_str_new(buffer + *position + 9, length - 4);
            } else {
                data = rb_str_new(buffer + *position + 5, length);
            }
            st = INT2FIX(subtype);
            argv[0] = data;
            argv[1] = st;
            value = rb_class_new_instance(2, argv, Binary);
            *position += length + 5;
            break;
        }
    case 6:
        {
            value = Qnil;
            break;
        }
    case 7:
        {
            VALUE str = rb_str_new(buffer + *position, 12);
            VALUE oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
            value = rb_class_new_instance(1, &oid, ObjectId);
            *position += 12;
            break;
        }
    case 8:
        {
            value = buffer[(*position)++] ? Qtrue : Qfalse;
            break;
        }
    case 9:
        {
            long long millis;
            memcpy(&millis, buffer + *position, 8);

            value = rb_time_new(millis / 1000, (millis % 1000) * 1000);
            value = rb_funcall(value, utc_method, 0);
            *position += 8;
            break;
        }
    case 10:
        {
            value = Qnil;
            break;
        }
    case 11:
        {
            int pattern_length = (int)strlen(buffer + *position);
            VALUE pattern = STR_NEW(buffer + *position, pattern_length);
            int flags_length, flags = 0, i = 0;
            VALUE argv[3];
            *position += pattern_length + 1;

            flags_length = (int)strlen(buffer + *position);
            for (i = 0; i < flags_length; i++) {
                char flag = buffer[*position + i];
                if (flag == 'i') {
                    flags |= IGNORECASE;
                }
                else if (flag == 'm') {
                    flags |= MULTILINE;
                }
                else if (flag == 's') {
                    flags |= MULTILINE;
                }
                else if (flag == 'x') {
                    flags |= EXTENDED;
                }
            }
            argv[0] = pattern;
            argv[1] = INT2FIX(flags);
            value = rb_class_new_instance(2, argv, Regexp);
            *position += flags_length + 1;
            break;
        }
    case 12:
        {
            int collection_length;
            VALUE collection, str, oid, id, argv[2];
            collection_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            collection = STR_NEW(buffer + *position, collection_length);
            *position += collection_length + 1;

            str = rb_str_new(buffer + *position, 12);
            oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
            id = rb_class_new_instance(1, &oid, ObjectId);
            *position += 12;

            argv[0] = collection;
            argv[1] = id;
            value = rb_class_new_instance(2, argv, DBRef);
            break;
        }
    case 14:
        {
            int value_length;
            memcpy(&value_length, buffer + *position, 4);
            value = ID2SYM(rb_intern(buffer + *position + 4));
            *position += value_length + 4;
            break;
        }
    case 15:
        {
            int code_length, scope_size;
            VALUE code, scope, argv[2];
            *position += 4;
            code_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            code = STR_NEW(buffer + *position, code_length);
            *position += code_length + 1;

            memcpy(&scope_size, buffer + *position, 4);
            scope = elements_to_hash(buffer + *position + 4, scope_size - 5);
            *position += scope_size;

            argv[0] = code;
            argv[1] = scope;
            value = rb_class_new_instance(2, argv, Code);
            break;
        }
    case 16:
        {
            int i;
            memcpy(&i, buffer + *position, 4);
            value = LL2NUM(i);
            *position += 4;
            break;
        }
    case 17:
        {
            int sec, inc;
            VALUE argv[2];
            memcpy(&inc, buffer + *position, 4);
            memcpy(&sec, buffer + *position + 4, 4);
            argv[0] = INT2FIX(sec);
            argv[1] = INT2FIX(inc);
            value = rb_class_new_instance(2, argv, Timestamp);
            *position += 8;
            break;
        }
    case 18:
        {
            long long ll;
            memcpy(&ll, buffer + *position, 8);
            value = LL2NUM(ll);
            *position += 8;
            break;
        }
    case 127:
        {
            value = rb_class_new_instance(0, NULL, MaxKey);
            break;
        }
    default:
        {
            rb_raise(rb_eTypeError, "no c decoder for this type yet (%d)", type);
            break;
        }
    }
    return value;
}
Exemple #14
0
    void
cb_get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_resp_t *resp)
{
    struct cb_context_st *ctx = (struct cb_context_st *)cookie;
    struct cb_bucket_st *bucket = ctx->bucket;
    VALUE key, val, flags, cas, exc = Qnil, res, raw;

    ctx->nqueries--;
    key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
    cb_strip_key_prefix(bucket, key);

    if (error != LCB_KEY_ENOENT || !ctx->quiet) {
        exc = cb_check_error(error, "failed to get value", key);
        if (exc != Qnil) {
            rb_ivar_set(exc, cb_id_iv_operation, cb_sym_get);
            ctx->exception = exc;
        }
    }

    flags = ULONG2NUM(resp->v.v0.flags);
    cas = ULL2NUM(resp->v.v0.cas);
    raw = STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes);
    val = cb_decode_value(ctx->transcoder, raw, resp->v.v0.flags, ctx->transcoder_opts);
    if (rb_obj_is_kind_of(val, rb_eStandardError)) {
        VALUE exc_str = rb_funcall(val, cb_id_to_s, 0);
        VALUE msg = rb_funcall(rb_mKernel, cb_id_sprintf, 3,
                rb_str_new2("unable to convert value for key \"%s\": %s"), key, exc_str);
        ctx->exception = rb_exc_new3(cb_eValueFormatError, msg);
        rb_ivar_set(ctx->exception, cb_id_iv_operation, cb_sym_get);
        rb_ivar_set(ctx->exception, cb_id_iv_key, key);
        rb_ivar_set(ctx->exception, cb_id_iv_inner_exception, val);
        val = Qnil;
    }
    if (bucket->async) { /* asynchronous */
        if (ctx->proc != Qnil) {
            res = rb_class_new_instance(0, NULL, cb_cResult);
            rb_ivar_set(res, cb_id_iv_error, exc);
            rb_ivar_set(res, cb_id_iv_operation, cb_sym_get);
            rb_ivar_set(res, cb_id_iv_key, key);
            rb_ivar_set(res, cb_id_iv_value, val);
            rb_ivar_set(res, cb_id_iv_flags, flags);
            rb_ivar_set(res, cb_id_iv_cas, cas);
            cb_proc_call(bucket, ctx->proc, 1, res);
        }
    } else {                /* synchronous */
        if (NIL_P(exc) && error != LCB_KEY_ENOENT) {
            if (ctx->extended) {
                val = rb_ary_new3(3, val, flags, cas);
            }
            if (ctx->all_replicas) {
                VALUE ary = rb_hash_aref(ctx->rv, key);
                if (NIL_P(ary)) {
                    ary = rb_ary_new();
                    rb_hash_aset(ctx->rv, key, ary);
                }
                rb_ary_push(ary, val);
            } else {
                rb_hash_aset(ctx->rv, key, val);
            }
        }
    }

    if (ctx->nqueries == 0) {
        ctx->proc = Qnil;
        if (bucket->async) {
            cb_context_free(ctx);
        }
    }
    (void)handle;
}
Exemple #15
0
void Main (Closure_clp self)
{
    FB_st *st;
    IOEntryMod_clp emod;

    int i;
    
    TRC(printf("FB/MGA: entered\n"));
 
    st = (FB_st *)Heap$Malloc(Pvs(heap), 
			      sizeof(FB_st));
    if (st == NULL) 
	RAISE_Heap$NoMemory();

    memset(st, 0, sizeof(FB_st));

    CL_INIT(st->cl, &fb_ms, st);


    /* Before we do anything, see if we can find a framebuffer device
       that we understand. */

    st->cardbase = (Pixel_t *) MGAInit(FB_WIDTH, FB_HEIGHT, FB_DEPTH, FB_MODE);

    TRC(printf("st->cardbase = %p\n", st->cardbase));

    if(!st->cardbase) {
	fprintf(stderr, "Failed to initialise MGA device\n");

	Heap$Free(Pvs(heap), st);

	return;
    }

#ifdef TEST_CARD
    test_card16a( (uint16_t *) st->cardbase );
#else
    memset((uchar_t *) st->cardbase, 0, 
	   FB_WIDTH * FB_HEIGHT * (FB_DEPTH/8) );
#endif	

    /* Init state */
    st->qosleft = 100;
    st->cursched = 0;
    st->schedndx = 0;
    for (i = 0; i < FB_SCHEDLEN; i++) {
	st->sched[0][i] = st->sched[1][i] = 0;
    }
    
    /* Initialise window DS */
    for (i = 0 ; i < FB_MAX_WINDOWS; i++) {
	FB_Window *w = &st->window[i];
	w->wid  = i;
	w->free = True;
	w->tagword = w->tag  = w->wid;

	/* extend the tag to be a full word (32 or 64 bits) wide */
	w->tagword |= (w->tagword<<8);
	w->tagword |= (w->tagword<<16);
	/* Generates harmless overflow warning on 32bit architectures */
	w->tagword |= (w->tagword<<32);

    }
    
    /* Initialise stream DS */
    for (i = 0 ; i < FB_MAX_STREAMS; i++) {
	FB_Stream *s = &st->stream[i];
	s->sid  = i;
	s->free = True;
	s->qos  = 0;
    }

    TRC(printf("About to create an entry...\n"));

    /* Create an entry*/
    emod = NAME_FIND ("modules>IOEntryMod", IOEntryMod_clp);
    st->fbentry = IOEntryMod$New (emod, Pvs(actf), Pvs(vp),
				  VP$NumChannels (Pvs(vp)));    
    

    TRC(printf("About to grab stretches for FB and CLIP\n"));

    /* Grab stretches for FB and CLIP */
    {

	Stretch_clp           str;
	Stretch_Size          size;

	/* Get a stretch for clip RAM. Allocate a spare line of tiles
           at the start and end in case we need to blit over the edges */

	str    = STR_NEW(sizeof(tag_t)*FB_WIDTH*(FB_HEIGHT+16));
	if (!str) {
	    fprintf(stderr,"Couldn't get stretch");
	}
	st->clipstr = str;
	st->clipbase = (tag_t *) STR_RANGE(str, &size);
	st->clip = st->clipbase + (FB_WIDTH * 8);

	if (!st->clip || size < (FB_WIDTH*(FB_HEIGHT+16))) {
	    fprintf(stderr,"Stretch bogus\n");
	}
	TRC(fprintf(stderr,"FB: Clip RAM at %p size %lx\n", st->clip, size));	
    }
    TRC(printf("About to init clip RAM\n"));

    /* Initialise the clip RAM */
    InitClipRAM(&st->cl);

    TRC(printf("About to add dev>fblite to namespace\n"));
    CX_ADD("dev>fblite", st->cardbase, addr_t);

    TRC(printf("About to init blitting code\n"));
    /* Init the blitting code */
    blit_init(st);

    /* Turn on cursor */
    TRC(printf("About to turn on cursor\n"));
    MGALoadCursor(st->cardbase, CURSOR_IDX, CURSOR_BITS);
    MGAMoveCursor(st->cardbase, CURSOR_IDX, CURSOR_INITX, CURSOR_INITY);

    /* Export management interface */
    TRC(printf("About to export management interface\n"));
    IDC_EXPORT ("dev>FB", FB_clp, &st->cl);
    /* Go into a loop to service all the clients */


    /* Launch WSSvr */

    TRC(printf("Trying to launch wssvr\n"));
    TRY {
	Closure_clp wssvr;

	wssvr = NAME_FIND("modules>WSSvr", Closure_clp);
	
	Threads$Fork(Pvs(thds), wssvr->op->Apply, wssvr->st, 0);

	st->wssvr_shares_domain = True;
    } CATCH_ALL {
	printf("Couldn't launch WSSvr - exception %s\n",
	       exn_ctx.cur_exception);
    } ENDTRY;

    TRC(printf("FB/MGA: Init Done. (%ix%i %ibpp mode %i)\n",
	       FB_WIDTH,FB_HEIGHT,FB_DEPTH,FB_MODE));
    blit_loop(st);
}
Exemple #16
0
void boot(Rd_clp rd, bool_t verbose, string_t cmdline)
{
#ifdef INTEL
    uint32_t NOCLOBBER length;
    uint32_t start, slen;
    uint8_t * NOCLOBBER buff;
    Stretch_clp stretch;
    
    length=Rd$Length(rd);

    /* Read the header of the file to try to work out what it is */

    buff=Heap$Malloc(Pvs(heap), 512);
    Rd$GetChars(rd, buff, 512);

    if (buff[510]==0x55 && buff[511]==0xaa) {
	if (verbose) printf(
	    "Traditional bootable Nemesis image with %d setup blocks.\n",
	    buff[497]);
	start=512*(buff[497]+1);
    } else if (buff[0]==0xfa && buff[1]==0xfc ) {
	if (verbose) printf("Hmm... looks like a bare Nemesis image.\n");
	start=0;
    } else {
	printf("This does not look like a Nemesis image.\n");
	return;
    }

    Heap$Free(Pvs(heap), buff);

    length-=start;

    /* Get a stretch of the appropriate size */
    stretch = STR_NEW(length);
    buff    = STR_RANGE(stretch, &slen);

    /* Read the image */
    Rd$Seek(rd, start);
#define PKTSIZE 8192
    {
	char *bufptr = buff;
	int n;
	int togo = length;

	while (togo) {
	    n = Rd$GetChars(rd, bufptr, PKTSIZE);
	    togo -= n;
	    bufptr += n;
	    printf("."); fflush(stdout);
	} 
    }
    printf("\n");

    /* now shut down any Ethernet cards, so we don't get anything DMAed
     * over the image while it boots */
    /* XXX AND This is a privileged operation.  And we shouldn't really
     * dive at the Netif interface directly. */
    /* XXX SDE we might be in a UDPnash at the moment, so there should be
     * NO OUTPUT after this point */
    verbose=False;
    {
	Type_Any any;
	Netif_clp netif;
	const char * const downlist[] = {"de4x5-0",
					 "de4x5-1",
					 /* don't need 3c509, since no DMA */
					 "eth0",
					 NULL};
	/* HACK: need to lose the "const", since Context$Get() doesn't
         * have it. */
	char ** NOCLOBBER eth = (char**)downlist;
	char buf[32];

	while(*eth)
	{
	    sprintf(buf, "dev>%s>control", *eth);

	    if (Context$Get(Pvs(root), buf, &any))
	    {
		if (verbose)
		{
		    printf("Shutting down %s... ", *eth);
		    fflush(stdout);
		}

		TRY {
		    netif = IDC_OPEN(buf, Netif_clp);
		} CATCH_ALL {
		    if (verbose)
			printf("failed: caught exception\n");
		    netif = NULL;
		} ENDTRY;

		if (netif && !Netif$Down(netif) && verbose)
		{
		    printf("failed: Netif$Down() error\n");
		    netif = NULL;
		}

		if (netif && verbose)
		    printf("ok\n");
	    }

	    eth++;
	}
    }

    if (verbose)
    {
	printf("Starting image...\n");
	PAUSE(MILLISECS(1000));
    }

    /* Chain to the new image */
    ENTER_KERNEL_CRITICAL_SECTION();
    ntsc_chain(buff, length, cmdline);
    LEAVE_KERNEL_CRITICAL_SECTION();

    printf("Bogosity: the new image was not started\n");
    printf("bogosity: (n) (slang); the degree of unusallness and brokenness of some item or event\n");
#else
    printf("Boot chaining not supported\n");
#endif
}
Exemple #17
0
static VALUE get_value(const char* buffer, int* position,
                       unsigned char type, struct deserialize_opts * opts) {
    VALUE value;
    switch (type) {
    case 255:
        {
            value = rb_class_new_instance(0, NULL, MinKey);
            break;
        }
    case 1:
        {
            double d;
            memcpy(&d, buffer + *position, 8);
            value = rb_float_new(d);
            *position += 8;
            break;
        }
    case 2:
    case 13:
        {
            int value_length;
            value_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            value = STR_NEW(buffer + *position, value_length);
            *position += value_length + 1;
            break;
        }
    case 3:
        {
            int size;
            memcpy(&size, buffer + *position, 4);
            if (strcmp(buffer + *position + 5, "$ref") == 0) { // DBRef
                VALUE argv[2];
                unsigned char id_type;
                int offset = *position + 10;
                int collection_length = *(int*)(buffer + offset) - 1;

                offset += 4;

                argv[0] = STR_NEW(buffer + offset, collection_length);
                offset += collection_length + 1;
                id_type = (unsigned char)buffer[offset];
                offset += 5;
                argv[1] = get_value(buffer, &offset, id_type, opts);
                value = rb_class_new_instance(2, argv, DBRef);
            } else {
                value = elements_to_hash(buffer + *position + 4, size - 5, opts);
            }
            *position += size;
            break;
        }
    case 4:
        {
            int size, end;
            memcpy(&size, buffer + *position, 4);
            end = *position + size - 1;
            *position += 4;

            value = rb_ary_new();
            while (*position < end) {
                VALUE to_append;
                unsigned char type = (unsigned char)buffer[(*position)++];
                int key_size = (int)strlen(buffer + *position);

                *position += key_size + 1; // just skip the key, they're in order.
                to_append = get_value(buffer, position, type, opts);
                rb_ary_push(value, to_append);
            }
            (*position)++;
            break;
        }
    case 5:
        {
            int length, subtype;
            VALUE data, st;
            VALUE argv[2];
            memcpy(&length, buffer + *position, 4);
            subtype = (unsigned char)buffer[*position + 4];
            if (subtype == 2) {
                data = rb_str_new(buffer + *position + 9, length - 4);
            } else {
                data = rb_str_new(buffer + *position + 5, length);
            }
            st = INT2FIX(subtype);
            argv[0] = data;
            argv[1] = st;
            value = rb_class_new_instance(2, argv, Binary);
            *position += length + 5;
            break;
        }
    case 6:
        {
            value = Qnil;
            break;
        }
    case 7:
        {
            VALUE str = rb_str_new(buffer + *position, 12);
            VALUE oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
            value = rb_class_new_instance(1, &oid, ObjectId);
            *position += 12;
            break;
        }
    case 8:
        {
            value = buffer[(*position)++] ? Qtrue : Qfalse;
            break;
        }
    case 9:
        {
            int64_t millis;
            memcpy(&millis, buffer + *position, 8);

            // Support 64-bit time values in 32 bit environments in Ruby > 1.9
            // Note: rb_time_num_new is not available pre Ruby 1.9
            #if RUBY_API_VERSION_CODE >= 10900
                #define add(x,y) (rb_funcall((x), '+', 1, (y)))
                #define mul(x,y) (rb_funcall((x), '*', 1, (y)))
                #define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y)))
                VALUE d, timev;
                d = LL2NUM(1000LL);
                timev = add(LL2NUM(millis / 1000), quo(LL2NUM(millis % 1000), d));
                value = rb_time_num_new(timev, Qnil);
            #else
                value = rb_time_new(millis / 1000, (millis % 1000) * 1000);
            #endif

            value = rb_funcall(value, utc_method, 0);
            *position += 8;
            break;
        }
    case 10:
        {
            value = Qnil;
            break;
        }
    case 11:
        {
            int pattern_length = (int)strlen(buffer + *position);
            VALUE pattern = STR_NEW(buffer + *position, pattern_length);
            int flags_length;
            VALUE argv[3], flags_str;
            *position += pattern_length + 1;

            flags_length = (int)strlen(buffer + *position);
            flags_str = STR_NEW(buffer + *position, flags_length);
            argv[0] = pattern;
            argv[1] = flags_str;
            value = rb_class_new_instance(2, argv, BSONRegex);

            if (opts->compile_regex == 1) {
                value = rb_funcall(value, rb_intern("try_compile"), 0);
            }
            *position += flags_length + 1;
            break;
        }
    case 12:
        {
            int collection_length;
            VALUE collection, str, oid, id, argv[2];
            collection_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            collection = STR_NEW(buffer + *position, collection_length);
            *position += collection_length + 1;

            str = rb_str_new(buffer + *position, 12);
            oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
            id = rb_class_new_instance(1, &oid, ObjectId);
            *position += 12;

            argv[0] = collection;
            argv[1] = id;
            value = rb_class_new_instance(2, argv, DBRef);
            break;
        }
    case 14:
        {
            int value_length;
            memcpy(&value_length, buffer + *position, 4);
            value = ID2SYM(rb_intern(buffer + *position + 4));
            *position += value_length + 4;
            break;
        }
    case 15:
        {
            int code_length, scope_size;
            VALUE code, scope, argv[2];
            *position += 4;
            code_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            code = STR_NEW(buffer + *position, code_length);
            *position += code_length + 1;

            memcpy(&scope_size, buffer + *position, 4);
            scope = elements_to_hash(buffer + *position + 4, scope_size - 5, opts);
            *position += scope_size;

            argv[0] = code;
            argv[1] = scope;
            value = rb_class_new_instance(2, argv, Code);
            break;
        }
    case 16:
        {
            int i;
            memcpy(&i, buffer + *position, 4);
            value = LL2NUM(i);
            *position += 4;
            break;
        }
    case 17:
        {
            unsigned int sec, inc;
            VALUE argv[2];
            memcpy(&inc, buffer + *position, 4);
            memcpy(&sec, buffer + *position + 4, 4);
            argv[0] = UINT2NUM(sec);
            argv[1] = UINT2NUM(inc);
            value = rb_class_new_instance(2, argv, Timestamp);
            *position += 8;
            break;
        }
    case 18:
        {
            long long ll;
            memcpy(&ll, buffer + *position, 8);
            value = LL2NUM(ll);
            *position += 8;
            break;
        }
    case 127:
        {
            value = rb_class_new_instance(0, NULL, MaxKey);
            break;
        }
    default:
        {
            rb_raise(rb_eTypeError, "no c decoder for this type yet (%d)", type);
            break;
        }
    }
    return value;
}