/** * 非阻塞读取数据 * return 读取的总数据,错误设置在g_errorno上 */ ssize_t read_buffer( int fd, buffer_t *pbuf ) { assert(fd >= 0); assert( pbuf != NULL); block_t *pb = NULL; int n, total, size; total = 0; g_errno = 1; //无错误 NONREAD: pb = pbuf->tail; if ( NULL == pb || BLOCK_FULL(pb) ) { if ( add_block( pbuf ) < 0 ) { return -1; } pb = pbuf->tail; } size = BLOCK_REMAIN(pb); //空闲位置是 [end, BLOCK_DATA] n = read( fd, BLOCK_READADDR(pb), size ); log_message( LOG_DEBUG, "read %d bytes from fd[%d]", n, fd ); if ( n > 0 ) { g_errno = 1; total += n; pb->end += n; pbuf->size += n; //待发送数据大小 if ( n == size ) { goto NONREAD; //epoll的ET mode } } else if ( 0 == n ) { //已经关闭读 g_errno = 0; } else { switch (errno) { #ifdef EWOULDBLOCK case EWOULDBLOCK: #else # ifdef EAGAIN case EAGAIN: # endif #endif case EINTR: g_errno = 1; //不是错误,本次读取结束,等待下次事件 break; default: g_errno = -1; log_message( LOG_ERROR, "readbuff: recv() error \"%s\" on file descriptor %d", strerror(errno), fd); } } return total; }
void* allocate_memory(int32_t size) { Block* block = get_block(size); if(block == NULL) { return NULL; } void* result = allocate_chunk_from_block(block); if(BLOCK_FULL(block)) { make_block_orphan(block); } return result; }