int main() { struct RingBuffer *h = NULL; int x = 10, y = INT_MAX, z = 2863311530, m = -3333; int offset_remove = 2; int offset_insert = 3; int offset_data = 4; assert(ringbuffer_init(&h, 3, sizeof(x)) == 0); assert(ringbuffer_push(h, (unsigned char *)&x) == RBE_SUCCESS); assert(ringbuffer_push(h, (unsigned char *)&y) == RBE_SUCCESS); assert(ringbuffer_full(h) != 0); assert(ringbuffer_pop(h) == RBE_SUCCESS); assert(ringbuffer_push(h, (unsigned char *)&z) == RBE_SUCCESS); assert(ringbuffer_full(h) != 0); assert(ringbuffer_resize(&h, 5) == RBE_SUCCESS); assert(ringbuffer_full(h) == 0); assert(ringbuffer_empty(h) == 0); assert(ringbuffer_push(h, (unsigned char *)&m) == RBE_SUCCESS); assert(ringbuffer_push(h, (unsigned char *)&x) == RBE_SUCCESS); assert(ringbuffer_full(h) != 0); { /* checking the data: x y z m x */ unsigned *off = (unsigned *) h; int *values = (int *) off + offset_data; assert(*(off + offset_remove) == 1 * sizeof(x)); assert(*(off + offset_insert) == 0); assert(values[0] == x); assert(values[1] == y); assert(values[2] == z); assert(values[3] == m); assert(values[4] == x); } ringbuffer_destroy(&h); return 0; }
void * mread_pull(struct mread_pool * self , int size) { if (self->active == -1) { return NULL; } struct socket *s = &self->sockets[self->active]; int rd_size = size; char * buffer = _ringbuffer_read(self, &rd_size); if (buffer) { self->skip += size; return buffer; } switch (s->status) { case SOCKET_READ: s->status = SOCKET_SUSPEND; case SOCKET_CLOSED: case SOCKET_SUSPEND: return NULL; default: assert(s->status == SOCKET_POLLIN); break; } int sz = size - rd_size; int rd = READBLOCKSIZE; if (rd < sz) { rd = sz; } int id = self->active; struct ringbuffer * rb = self->rb; struct ringbuffer_block * blk = ringbuffer_alloc(rb , rd); while (blk == NULL) { int collect_id = ringbuffer_collect(rb); mread_close_client(self , collect_id); if (id == collect_id) { return NULL; } blk = ringbuffer_alloc(rb , rd); } buffer = (char *)(blk + 1); for (;;) { int bytes = recv(s->fd, buffer, rd, MSG_DONTWAIT); if (bytes > 0) { ringbuffer_resize(rb, blk , bytes); if (bytes < sz) { _link_node(rb, self->active, s , blk); s->status = SOCKET_SUSPEND; return NULL; } s->status = SOCKET_READ; break; } if (bytes == 0) { ringbuffer_resize(rb, blk, 0); _close_active(self); return NULL; } if (bytes == -1) { switch(errno) { case EWOULDBLOCK: ringbuffer_resize(rb, blk, 0); s->status = SOCKET_SUSPEND; return NULL; case EINTR: continue; default: ringbuffer_resize(rb, blk, 0); _close_active(self); return NULL; } } } _link_node(rb, self->active , s , blk); void * ret; int real_rd = ringbuffer_data(rb, s->node , size , self->skip, &ret); if (ret) { self->skip += size; return ret; } assert(real_rd == size); struct ringbuffer_block * temp = ringbuffer_alloc(rb, size); while (temp == NULL) { int collect_id = ringbuffer_collect(rb); mread_close_client(self , collect_id); if (id == collect_id) { return NULL; } temp = ringbuffer_alloc(rb , size); } temp->id = id; if (s->temp) { ringbuffer_link(rb, temp, s->temp); } s->temp = temp; ret = ringbuffer_copy(rb, s->node, self->skip, temp); assert(ret); self->skip += size; return ret; }