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 (;;) { #if defined(WIN32) int flags=0; int recv_bytes; int bytes = recv(s->fd, buffer, rd, 0); //recv zero data for iocp CreateIoCompletionPort(s->fd,self->iocp,s->fd,0); ZeroMemory(&(s->ol),sizeof(OVERLAPPED)); if (WSARecv(s->fd, &(s->buffer),1, &recv_bytes, &flags, &(s->ol), NULL) == SOCKET_ERROR) { if(GetLastError() !=WSA_IO_PENDING){ ringbuffer_shrink(rb, blk, 0); _close_active(self); printf("GetLastError is : %d \n",GetLastError()); return NULL; } } #else int bytes = recv(s->fd, buffer, rd, MSG_DONTWAIT); #endif if (bytes > 0) { ringbuffer_shrink(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_shrink(rb, blk, 0); _close_active(self); return NULL; } #if !defined(WIN32) if (bytes == -1) { switch(errno) { case EWOULDBLOCK: ringbuffer_shrink(rb, blk, 0); s->status = SOCKET_SUSPEND; return NULL; case EINTR: continue; default: ringbuffer_shrink(rb, blk, 0); _close_active(self); return NULL; } } #else if(bytes == -1){ ringbuffer_shrink(rb, blk, 0); _close_active(self); return NULL; } #endif } _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; }
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; }