ACL_MEM_SLICE *acl_mem_slice_init(int base, int nslice, int nalloc_gc, unsigned int slice_flag) { const char *myname = "acl_mem_slice_init"; ACL_MEM_SLICE *mem_slice; if (__mem_slice_key != (acl_pthread_key_t) -1) { acl_msg_error("%s(%d): has been init", myname, __LINE__); return NULL; } __mem_base = base; __mem_nslice = nslice; __mem_nalloc_gc = nalloc_gc < 10 ? 10 : nalloc_gc; __mem_slice_flag = slice_flag; __mem_list_init_size = nalloc_gc / 10; if (__mem_list_init_size < 1000) __mem_list_init_size = 1000; else if (__mem_list_init_size > 1000000) __mem_list_init_size = 1000000; /* 主线程获得自己的线程局部存储内存池 */ mem_slice = mem_slice_create(); if (mem_slice == NULL) acl_msg_fatal("%s(%d): mem_slice null", myname, __LINE__); /* 创建进程空间内全局的内存池集合对象, 其存储所有线程的存储内存池句柄 */ __mem_slice_list = private_array_create(10); __mem_slice_list_lock = thread_mutex_create(); private_array_push(__mem_slice_list, mem_slice); mem_slice->slice_list = __mem_slice_list; mem_slice->slice_list_lock = __mem_slice_list_lock; if (__mem_slice_list == NULL) acl_msg_fatal("%s(%d): __mem_slice_list null", myname, __LINE__); if (__mem_slice_list_lock == NULL) acl_msg_fatal("%s(%d): __mem_slice_list_lock null", myname, __LINE__); atexit(free_global_ctx); mem_slice->tls_key = __mem_slice_key; acl_mem_hook(tls_mem_alloc, tls_mem_calloc, tls_mem_realloc, tls_mem_strdup, tls_mem_strndup, tls_mem_memdup, tls_mem_free); acl_msg_info("%s(%d): use ACL_MEM_SLICE, with tls", myname, __LINE__); return mem_slice; }
static ACL_MEM_SLICE *mem_slice_create(void) { const char *myname = "mem_slice_create"; ACL_MEM_SLICE *mem_slice; acl_pthread_once(&once_control, slice_key_init); if (__mem_slice_key == (acl_pthread_key_t) -1) acl_msg_fatal("%s(%d): __mem_slice_key(%d) invalid," " call acl_mem_slice_init or acl_mem_slice_set first", myname, __LINE__, (int) __mem_slice_key); mem_slice = acl_pthread_getspecific(__mem_slice_key); if (mem_slice != NULL) return mem_slice; mem_slice = (ACL_MEM_SLICE*) acl_default_calloc(__FILE__, __LINE__, 1, sizeof(ACL_MEM_SLICE)); if (mem_slice == NULL) acl_msg_fatal("%s(%d): can't alloc for mem_slice(%s)", myname, __LINE__, acl_last_serror()); mem_slice->slice_pool = acl_slice_pool_create(__mem_base, __mem_nslice, __mem_slice_flag); mem_slice->tid = (unsigned long) acl_pthread_self(); mem_slice->list = private_array_create(__mem_list_init_size); MUTEX_INIT(mem_slice); mem_slice->tls_key = __mem_slice_key; mem_slice->nalloc_gc = __mem_nalloc_gc; mem_slice->slice_flag = __mem_slice_flag; acl_pthread_setspecific(__mem_slice_key, mem_slice); if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) __main_mem_slice = mem_slice; acl_msg_info("%s(%d): thread(%ld) set myown mem_slice(%p)", myname, __LINE__, (long) mem_slice->tid, mem_slice); return mem_slice; }
ACL_VSTREAM *private_vstream_fdopen(ACL_SOCKET fd, unsigned int oflags, size_t buflen, int rw_timeo, int fdtype) { ACL_VSTREAM *stream = NULL; stream = (ACL_VSTREAM *) calloc(1, sizeof(ACL_VSTREAM)); acl_assert(stream); if (buflen < ACL_VSTREAM_DEF_MAXLEN) buflen = ACL_VSTREAM_DEF_MAXLEN; /* XXX: 只有非监听流才需要有读缓冲区 */ if ((fdtype & ACL_VSTREAM_TYPE_LISTEN_INET) || (fdtype & ACL_VSTREAM_TYPE_LISTEN_UNIX)) { fdtype |= ACL_VSTREAM_TYPE_LISTEN; stream->read_buf = NULL; } else { stream->read_buf = (unsigned char *) malloc(buflen + 1); acl_assert(stream->read_buf != NULL); } if (fdtype == 0) fdtype = ACL_VSTREAM_TYPE_SOCK; stream->read_buf_len = (int) buflen; stream->type = fdtype; ACL_VSTREAM_SOCK(stream) = fd; #ifdef ACL_WINDOWS stream->iocp_sock = ACL_SOCKET_INVALID; #endif stream->read_ptr = stream->read_buf; stream->oflags = oflags; ACL_SAFE_STRNCPY(stream->errbuf, "OK", sizeof(stream->errbuf)); if (rw_timeo > 0) stream->rw_timeout = rw_timeo; else stream->rw_timeout = 0; stream->sys_getc = __sys_getc; if (fdtype == ACL_VSTREAM_TYPE_FILE) { stream->fread_fn = acl_file_read; stream->fwrite_fn = acl_file_write; stream->fwritev_fn = acl_file_writev; stream->fclose_fn = acl_file_close; } else { stream->read_fn = acl_socket_read; stream->write_fn = acl_socket_write; stream->writev_fn = acl_socket_writev; stream->close_fn = acl_socket_close; } stream->addr_peer = NULL; stream->addr_local = NULL; stream->path = NULL; stream->close_handle_lnk = private_array_create(5); if (stream->close_handle_lnk == NULL) { free(stream->read_buf); free(stream); return (NULL); } return (stream); }