コード例 #1
0
ファイル: streamsservice.c プロジェクト: eclipse/tcf.agent
int virtual_stream_get_data(VirtualStream * stream, char * buf, size_t buf_size, size_t * data_size, int * eos) {
    size_t len;

    assert(stream->magic == STREAM_MAGIC);
    len = (stream->buf_inp + stream->buf_len - stream->buf_out) % stream->buf_len;

    if (len > buf_size) {
        len = buf_size;
        *eos = 0;
    }
    else {
        *eos = stream->eos_inp;
    }
    *data_size = len;
    if (*eos) stream->eos_out = 1;
    if (stream->buf_out + len <= stream->buf_len) {
        memcpy(buf, stream->buf + stream->buf_out, len);
    }
    else {
        size_t x = stream->buf_len - stream->buf_out;
        size_t y = len - x;
        memcpy(buf, stream->buf + stream->buf_out, x);
        memcpy(buf + x, stream->buf, y);
    }
    if (stream->access & VS_ENABLE_REMOTE_WRITE) {
        LINK * l;
        for (l = stream->clients.next; l != &stream->clients; l = l->next) {
            StreamClient * client = stream2client(l);
            if (!list_is_empty(&client->write_requests)) {
                WriteRequest * r = client2write_request(client->write_requests.next);
                size_t done = 0;
                int error = 0;
                if (virtual_stream_add_data(client->stream, r->data + r->offs,
                    r->size - r->offs, &done, r->eos) < 0) error = errno;
                r->offs += done;
                if (error || r->offs >= r->size) {
                    delete_write_request(r, error);
                }
                while (error && !list_is_empty(&client->write_requests)) {
                    r = client2write_request(client->write_requests.next);
                    delete_write_request(r, ERR_COMMAND_CANCELLED);
                }
            }
        }
    }
    if ((stream->access & VS_ENABLE_REMOTE_READ) == 0 && len > 0) {
        stream->buf_out = (stream->buf_out + len) % stream->buf_len;
        assert(!*eos || stream->buf_out == stream->buf_inp);
        if (!stream->space_available_posted) {
            post_event(notify_space_available, stream);
            stream->space_available_posted = 1;
        }
    }
    return 0;
}
コード例 #2
0
static void delete_client(StreamClient * client) {
    VirtualStream * stream = client->stream;
    Trap trap;
    LINK * n;

    assert(stream->ref_cnt > 0);
    if (set_trap(&trap)) {
        send_event_stream_disposed(&client->channel->out, stream);
        clear_trap(&trap);
    }
    else {
        trace(LOG_ALWAYS, "Exception sending stream deleted event: %d %s",
              trap.error, errno_to_str(trap.error));
    }
    list_remove(&client->link_hash);
    list_remove(&client->link_stream);
    list_remove(&client->link_all);
    for (n = client->read_requests.next; n != &client->read_requests;) {
        ReadRequest * r = client2read_request(n);
        n = n->next;
        delete_read_request(r);
    }
    for (n = client->write_requests.next; n != &client->write_requests;) {
        WriteRequest * r = client2write_request(n);
        n = n->next;
        delete_write_request(r, ERR_COMMAND_CANCELLED);
    }
    loc_free(client);
    if (--stream->ref_cnt == 0) {
        assert(list_is_empty(&stream->clients));
        assert(stream->deleted);
        post_event(delete_stream, stream);
    }
    else if (stream->access & VS_ENABLE_REMOTE_READ) {
        advance_stream_buffer(stream);
    }
}