swMemoryPool *swRingBuffer_new(uint32_t size, uint8_t shared) { void *mem = (shared == 1) ? sw_shm_malloc(size) : sw_malloc(size); if (mem == NULL) { swWarn("malloc(%d) failed.", size); return NULL; } swRingBuffer *object = mem; mem = (char *) mem + sizeof(swRingBuffer); bzero(object, sizeof(swRingBuffer)); object->size = (size - sizeof(swRingBuffer) - sizeof(swMemoryPool)); object->shared = shared; swMemoryPool *pool = mem; mem = (char *) mem + sizeof(swMemoryPool); pool->object = object; pool->destroy = swRingBuffer_destory; pool->free = swRingBuffer_free; pool->alloc = swRingBuffer_alloc; object->memory = mem; swDebug("memory: ptr=%p", mem); return pool; }
/** * return the package total length */ ssize_t swProtocol_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t size) { uint16_t length_offset = protocol->package_length_offset; uint8_t package_length_size = protocol->get_package_length_size ? protocol->get_package_length_size(conn) : protocol->package_length_size; int32_t body_length; /** * no have length field, wait more data */ if (size < length_offset + package_length_size) { protocol->real_header_length = length_offset + package_length_size; return 0; } body_length = swoole_unpack(protocol->package_length_type, data + length_offset); //Length error //Protocol length is not legitimate, out of bounds or exceed the allocated length if (body_length < 0) { swWarn("invalid package, remote_addr=%s:%d, length=%d, size=%d.", swConnection_get_ip(conn), swConnection_get_port(conn), body_length, size); return SW_ERR; } swDebug("length=%d", protocol->package_body_offset + body_length); //total package length return protocol->package_body_offset + body_length; }
static void* swRingBuffer_alloc(swMemoryPool *pool, uint32_t size) { assert(size > 0); swRingBuffer *object = pool->object; swRingBuffer_item *item; uint32_t capacity; uint32_t alloc_size = size + sizeof(swRingBuffer_item); if (object->free_count > 0) { swRingBuffer_collect(object); } if (object->status == 0) { if (object->alloc_offset + alloc_size >= object->size) { uint32_t skip_n = object->size - object->alloc_offset; item = object->memory + object->alloc_offset; item->lock = 0; item->length = skip_n - sizeof(swRingBuffer_item); sw_atomic_t *free_count = &object->free_count; sw_atomic_fetch_add(free_count, 1); object->alloc_offset = 0; object->status = 1; capacity = object->collect_offset - object->alloc_offset; } else { capacity = object->size - object->alloc_offset; } } else { capacity = object->collect_offset - object->alloc_offset; } if (capacity < alloc_size) { return NULL; } item = object->memory + object->alloc_offset; item->lock = 1; item->length = size; item->index = object->alloc_count; object->alloc_offset += alloc_size; object->alloc_count ++; swDebug("alloc: ptr=%d", (void *)item->data - object->memory); return item->data; }
static void swRingBuffer_free(swMemoryPool *pool, void *ptr) { swRingBuffer *object = pool->object; swRingBuffer_item *item = (swRingBuffer_item *) ((char *) ptr - sizeof(swRingBuffer_item)); assert(ptr >= object->memory); assert((char* )ptr <= (char * ) object->memory + object->size); assert(item->lock == 1); if (item->lock != 1) { swDebug("invalid free: index=%d, ptr=%p", item->index, (void * )((void * )item->data - object->memory)); } else { item->lock = 0; } swDebug("free: ptr=%p", (void * )((void * )item->data - object->memory)); sw_atomic_t *free_count = &object->free_count; sw_atomic_fetch_add(free_count, 1); }