int log_init_ex(LogContext *pContext) { int result; memset(pContext, 0, sizeof(LogContext)); pContext->log_level = LOG_INFO; pContext->log_fd = STDERR_FILENO; pContext->time_precision = LOG_TIME_PRECISION_SECOND; strcpy(pContext->rotate_time_format, "%Y%m%d_%H%M%S"); pContext->log_buff = (char *)malloc(LOG_BUFF_SIZE); if (pContext->log_buff == NULL) { fprintf(stderr, "malloc %d bytes fail, " \ "errno: %d, error info: %s", \ LOG_BUFF_SIZE, errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } pContext->pcurrent_buff = pContext->log_buff; if ((result=init_pthread_lock(&(pContext->log_thread_lock))) != 0) { return result; } return 0; }
int blocked_queue_init(struct fast_blocked_queue *pQueue) { int result; if ((result=init_pthread_lock(&(pQueue->lock))) != 0) { logError("file: "__FILE__", line: %d, " "init_pthread_lock fail, errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } result = pthread_cond_init(&(pQueue->cond), NULL); if (result != 0) { logError("file: "__FILE__", line: %d, " "pthread_cond_init fail, " "errno: %d, error info: %s", __LINE__, result, STRERROR(result)); return result; } pQueue->head = NULL; pQueue->tail = NULL; return 0; }
int conn_pool_init(ConnectionPool *cp, int connect_timeout, \ const int max_count_per_entry, const int max_idle_time) { int result; if ((result=init_pthread_lock(&cp->lock)) != 0) { return result; } cp->connect_timeout = connect_timeout; cp->max_count_per_entry = max_count_per_entry; cp->max_idle_time = max_idle_time; return hash_init(&(cp->hash_array), simple_hash, 1024, 0.75); }
int fast_mblock_manager_init() { int result; if ((result=init_pthread_lock(&(mblock_manager.lock))) != 0) { /*logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result));*/ return result; } INIT_HEAD(&mblock_manager.head); mblock_manager.initialized = true; return 0; }
int task_queue_init(struct fast_task_queue *pQueue) { int result; if ((result=init_pthread_lock(&(pQueue->lock))) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } pQueue->head = NULL; pQueue->tail = NULL; return 0; }
int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size, const int alloc_elements_once, fast_mblock_alloc_init_func init_func, const bool need_lock) { int result; if (element_size <= 0) { logError("file: "__FILE__", line: %d, " \ "invalid block size: %d", \ __LINE__, element_size); return EINVAL; } mblock->element_size = MEM_ALIGN(element_size); if (alloc_elements_once > 0) { mblock->alloc_elements_once = alloc_elements_once; } else { int block_size; block_size = MEM_ALIGN(sizeof(struct fast_mblock_node) \ + mblock->element_size); mblock->alloc_elements_once = (1024 * 1024) / block_size; } if (need_lock && (result=init_pthread_lock(&(mblock->lock))) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } mblock->alloc_init_func = init_func; mblock->malloc_chain_head = NULL; mblock->free_chain_head = NULL; mblock->delay_free_chain.head = NULL; mblock->delay_free_chain.tail = NULL; mblock->total_count = 0; mblock->need_lock = need_lock; return 0; }
int fast_mblock_init(struct fast_mblock_man *mblock, const int element_size, \ const int alloc_elements_once) { int result; if (element_size <= 0) { logError("file: "__FILE__", line: %d, " \ "invalid block size: %d", \ __LINE__, element_size); return EINVAL; } mblock->element_size = element_size; if (alloc_elements_once > 0) { mblock->alloc_elements_once = alloc_elements_once; } else { int block_size; block_size = sizeof(struct fast_mblock_node) + element_size; mblock->alloc_elements_once = (1024 * 1024) / block_size; } if ((result=init_pthread_lock(&(mblock->lock))) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } mblock->malloc_chain_head = NULL; mblock->free_chain_head = NULL; return 0; }
int hash_set_locks(HashArray *pHash, const int lock_count) { size_t bytes; pthread_mutex_t *lock; pthread_mutex_t *lock_end; if (pHash->locks != NULL) { return EEXIST; } if (lock_count <= 0) { return EINVAL; } //do NOT support rehash if (pHash->load_factor >= 0.10) { return EINVAL; } bytes = sizeof(pthread_mutex_t) * lock_count; pHash->locks = (pthread_mutex_t *)malloc(bytes); if (pHash->locks == NULL) { return ENOMEM; } pHash->lock_count = lock_count; lock_end = pHash->locks + lock_count; for (lock=pHash->locks; lock<lock_end; lock++) { init_pthread_lock(lock); } return 0; }
int storage_trunk_init() { int result; int i; int count; if (!g_if_trunker_self) { logError("file: "__FILE__", line: %d, " \ "I am not trunk server!", __LINE__); return 0; } if (trunk_init_flag != STORAGE_TRUNK_INIT_FLAG_NONE) { logWarning("file: "__FILE__", line: %d, " \ "trunk already inited!", __LINE__); return 0; } logDebug("file: "__FILE__", line: %d, " \ "storage trunk init ...", __LINE__); g_trunk_server.sock = -1; g_trunk_server.port = g_server_port; if ((result=init_pthread_lock(&trunk_file_lock)) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } if ((result=init_pthread_lock(&trunk_mem_lock)) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } if ((result=fast_mblock_init(&free_blocks_man, \ sizeof(FDFSTrunkNode), 0)) != 0) { return result; } if ((result=fast_mblock_init(&tree_nodes_man, \ sizeof(FDFSTrunkSlot), 0)) != 0) { return result; } tree_info_by_sizes = (AVLTreeInfo *)malloc(sizeof(AVLTreeInfo) * \ g_fdfs_store_paths.count); if (tree_info_by_sizes == NULL) { result = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, errno: %d, error info: %s", \ __LINE__, (int)(sizeof(AVLTreeInfo) * \ g_fdfs_store_paths.count), result, STRERROR(result)); return result; } for (i=0; i<g_fdfs_store_paths.count; i++) { if ((result=avl_tree_init(tree_info_by_sizes + i, NULL, \ storage_trunk_node_compare_size)) != 0) { logError("file: "__FILE__", line: %d, " \ "avl_tree_init fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } } if ((result=trunk_free_block_checker_init()) != 0) { return result; } if ((result=storage_trunk_load()) != 0) { return result; } count = 0; for (i=0; i<g_fdfs_store_paths.count; i++) { count += avl_tree_count(tree_info_by_sizes + i); } logInfo("file: "__FILE__", line: %d, " \ "tree by space size node count: %d, tree by trunk file id " \ "node count: %d, free block count: %d, " \ "trunk_total_free_space: %"PRId64, __LINE__, \ count, trunk_free_block_tree_node_count(), \ trunk_free_block_total_count(), \ g_trunk_total_free_space); /* { char filename[MAX_PATH_SIZE]; sprintf(filename, "%s/logs/tttt.dat", g_fdfs_base_path); trunk_free_block_tree_print(filename); } */ trunk_init_flag = STORAGE_TRUNK_INIT_FLAG_DONE; return 0; }
int free_queue_init(const int max_connections, const int min_buff_size, \ const int max_buff_size, const int arg_size) { struct fast_task_info *pTask; char *p; char *pCharEnd; int block_size; int alloc_size; int64_t total_size; int result; if ((result=init_pthread_lock(&(g_free_queue.lock))) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } block_size = sizeof(struct fast_task_info) + arg_size; alloc_size = block_size * max_connections; if (max_buff_size > min_buff_size) { total_size = alloc_size; g_free_queue.malloc_whole_block = false; } else { struct rlimit rlimit_data; rlim_t max_data_size; if (getrlimit(RLIMIT_DATA, &rlimit_data) < 0) { logError("file: "__FILE__", line: %d, " \ "call getrlimit fail, " \ "errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); return errno != 0 ? errno : EPERM; } if (rlimit_data.rlim_cur == RLIM_INFINITY) { max_data_size = 512 * 1024 * 1024; } else { max_data_size = rlimit_data.rlim_cur; if (max_data_size > 512 * 1024 * 1024) { max_data_size = 512 * 1024 * 1024; } } total_size = alloc_size+(int64_t)min_buff_size*max_connections; if (total_size <= max_data_size) { g_free_queue.malloc_whole_block = true; block_size += min_buff_size; } else { g_free_queue.malloc_whole_block = false; total_size = alloc_size; } } g_mpool = (struct fast_task_info *)malloc(total_size); if (g_mpool == NULL) { logError("file: "__FILE__", line: %d, " \ "malloc "INT64_PRINTF_FORMAT" bytes fail, " \ "errno: %d, error info: %s", \ __LINE__, total_size, errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } memset(g_mpool, 0, total_size); pCharEnd = ((char *)g_mpool) + total_size; for (p=(char *)g_mpool; p<pCharEnd; p += block_size) { pTask = (struct fast_task_info *)p; pTask->size = min_buff_size; pTask->arg = p + sizeof(struct fast_task_info); if (g_free_queue.malloc_whole_block) { pTask->data = (char *)pTask->arg + arg_size; } else { pTask->data = (char *)malloc(pTask->size); if (pTask->data == NULL) { free_queue_destroy(); logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, " \ "errno: %d, error info: %s", \ __LINE__, pTask->size, \ errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } } } g_free_queue.tail = (struct fast_task_info *)(pCharEnd - block_size); for (p=(char *)g_mpool; p<(char *)g_free_queue.tail; p += block_size) { pTask = (struct fast_task_info *)p; pTask->next = (struct fast_task_info *)(p + block_size); } g_free_queue.max_connections = max_connections; g_free_queue.min_buff_size = min_buff_size; g_free_queue.max_buff_size = max_buff_size; g_free_queue.arg_size = arg_size; g_free_queue.head = g_mpool; g_free_queue.tail->next = NULL; return 0; }
int storage_func_init(const char *filename, \ char *bind_addr, const int addr_size) { char *pBindAddr; char *pGroupName; char *pRunByGroup; char *pRunByUser; char *pFsyncAfterWrittenBytes; char *pThreadStackSize; char *pBuffSize; char *pIfAliasPrefix; char *pHttpDomain; IniContext iniContext; int result; int64_t fsync_after_written_bytes; int64_t thread_stack_size; int64_t buff_size; TrackerServerInfo *pServer; TrackerServerInfo *pEnd; /* while (nThreadCount > 0) { sleep(1); } */ if ((result=iniLoadFromFile(filename, &iniContext)) != 0) { logError("file: "__FILE__", line: %d, " \ "load conf file \"%s\" fail, ret code: %d", \ __LINE__, filename, result); return result; } do { if (iniGetBoolValue(NULL, "disabled", &iniContext, false)) { logError("file: "__FILE__", line: %d, " \ "conf file \"%s\" disabled=true, exit", \ __LINE__, filename); result = ECANCELED; break; } g_subdir_count_per_path=iniGetIntValue(NULL, \ "subdir_count_per_path", &iniContext, \ DEFAULT_DATA_DIR_COUNT_PER_PATH); if (g_subdir_count_per_path <= 0 || \ g_subdir_count_per_path > 256) { logError("file: "__FILE__", line: %d, " \ "conf file \"%s\", invalid subdir_count: %d", \ __LINE__, filename, g_subdir_count_per_path); result = EINVAL; break; } if ((result=storage_load_paths(&iniContext)) != 0) { break; } load_log_level(&iniContext); if ((result=log_set_prefix(g_fdfs_base_path, \ STORAGE_ERROR_LOG_FILENAME)) != 0) { break; } g_fdfs_connect_timeout = iniGetIntValue(NULL, "connect_timeout", \ &iniContext, DEFAULT_CONNECT_TIMEOUT); if (g_fdfs_connect_timeout <= 0) { g_fdfs_connect_timeout = DEFAULT_CONNECT_TIMEOUT; } g_fdfs_network_timeout = iniGetIntValue(NULL, "network_timeout", \ &iniContext, DEFAULT_NETWORK_TIMEOUT); if (g_fdfs_network_timeout <= 0) { g_fdfs_network_timeout = DEFAULT_NETWORK_TIMEOUT; } g_network_tv.tv_sec = g_fdfs_network_timeout; g_server_port = iniGetIntValue(NULL, "port", &iniContext, \ FDFS_STORAGE_SERVER_DEF_PORT); if (g_server_port <= 0) { g_server_port = FDFS_STORAGE_SERVER_DEF_PORT; } g_heart_beat_interval = iniGetIntValue(NULL, \ "heart_beat_interval", &iniContext, \ STORAGE_BEAT_DEF_INTERVAL); if (g_heart_beat_interval <= 0) { g_heart_beat_interval = STORAGE_BEAT_DEF_INTERVAL; } g_stat_report_interval = iniGetIntValue(NULL, \ "stat_report_interval", &iniContext, \ STORAGE_REPORT_DEF_INTERVAL); if (g_stat_report_interval <= 0) { g_stat_report_interval = STORAGE_REPORT_DEF_INTERVAL; } pBindAddr = iniGetStrValue(NULL, "bind_addr", &iniContext); if (pBindAddr == NULL) { *bind_addr = '\0'; } else { snprintf(bind_addr, addr_size, "%s", pBindAddr); } g_client_bind_addr = iniGetBoolValue(NULL, "client_bind", \ &iniContext, true); pGroupName = iniGetStrValue(NULL, "group_name", &iniContext); if (pGroupName == NULL) { logError("file: "__FILE__", line: %d, " \ "conf file \"%s\" must have item " \ "\"group_name\"!", \ __LINE__, filename); result = ENOENT; break; } if (pGroupName[0] == '\0') { logError("file: "__FILE__", line: %d, " \ "conf file \"%s\", " \ "group_name is empty!", \ __LINE__, filename); result = EINVAL; break; } snprintf(g_group_name, sizeof(g_group_name), "%s", pGroupName); if ((result=fdfs_validate_group_name(g_group_name)) != 0) \ { logError("file: "__FILE__", line: %d, " \ "conf file \"%s\", " \ "the group name \"%s\" is invalid!", \ __LINE__, filename, g_group_name); result = EINVAL; break; } result = fdfs_load_tracker_group_ex(&g_tracker_group, \ filename, &iniContext); if (result != 0) { break; } pEnd = g_tracker_group.servers + g_tracker_group.server_count; for (pServer=g_tracker_group.servers; pServer<pEnd; pServer++) { //printf("server=%s:%d\n", pServer->ip_addr, pServer->port); if (strcmp(pServer->ip_addr, "127.0.0.1") == 0) { logError("file: "__FILE__", line: %d, " \ "conf file \"%s\", " \ "tracker: \"%s:%d\" is invalid, " \ "tracker server ip can't be 127.0.0.1",\ __LINE__, filename, pServer->ip_addr, \ pServer->port); result = EINVAL; break; } } if (result != 0) { break; } g_sync_wait_usec = iniGetIntValue(NULL, "sync_wait_msec",\ &iniContext, STORAGE_DEF_SYNC_WAIT_MSEC); if (g_sync_wait_usec <= 0) { g_sync_wait_usec = STORAGE_DEF_SYNC_WAIT_MSEC; } g_sync_wait_usec *= 1000; g_sync_interval = iniGetIntValue(NULL, "sync_interval",\ &iniContext, 0); if (g_sync_interval < 0) { g_sync_interval = 0; } g_sync_interval *= 1000; if ((result=get_time_item_from_conf(&iniContext, \ "sync_start_time", &g_sync_start_time, 0, 0)) != 0) { break; } if ((result=get_time_item_from_conf(&iniContext, \ "sync_end_time", &g_sync_end_time, 23, 59)) != 0) { break; } g_sync_part_time = !((g_sync_start_time.hour == 0 && \ g_sync_start_time.minute == 0) && \ (g_sync_end_time.hour == 23 && \ g_sync_end_time.minute == 59)); g_max_connections = iniGetIntValue(NULL, "max_connections", \ &iniContext, DEFAULT_MAX_CONNECTONS); if (g_max_connections <= 0) { g_max_connections = DEFAULT_MAX_CONNECTONS; } if ((result=set_rlimit(RLIMIT_NOFILE, g_max_connections)) != 0) { break; } g_work_threads = iniGetIntValue(NULL, "work_threads", \ &iniContext, DEFAULT_WORK_THREADS); if (g_work_threads <= 0) { logError("file: "__FILE__", line: %d, " \ "item \"work_threads\" is invalid, " \ "value: %d <= 0!", __LINE__, g_work_threads); result = EINVAL; break; } pBuffSize = iniGetStrValue(NULL, \ "buff_size", &iniContext); if (pBuffSize == NULL) { buff_size = STORAGE_DEFAULT_BUFF_SIZE; } else if ((result=parse_bytes(pBuffSize, 1, &buff_size)) != 0) { return result; } g_buff_size = buff_size; if (g_buff_size < 4 * 1024 || \ g_buff_size < sizeof(TrackerHeader) + \ TRUNK_BINLOG_BUFFER_SIZE) { logError("file: "__FILE__", line: %d, " \ "item \"buff_size\" is too small, " \ "value: %d < %d or < %d!", __LINE__, \ g_buff_size, 4 * 1024, \ (int)sizeof(TrackerHeader) + \ TRUNK_BINLOG_BUFFER_SIZE); result = EINVAL; break; } g_disk_rw_separated = iniGetBoolValue(NULL, \ "disk_rw_separated", &iniContext, true); g_disk_reader_threads = iniGetIntValue(NULL, \ "disk_reader_threads", \ &iniContext, DEFAULT_DISK_READER_THREADS); if (g_disk_reader_threads < 0) { logError("file: "__FILE__", line: %d, " \ "item \"disk_reader_threads\" is invalid, " \ "value: %d < 0!", __LINE__, \ g_disk_reader_threads); result = EINVAL; break; } g_disk_writer_threads = iniGetIntValue(NULL, \ "disk_writer_threads", \ &iniContext, DEFAULT_DISK_WRITER_THREADS); if (g_disk_writer_threads < 0) { logError("file: "__FILE__", line: %d, " \ "item \"disk_writer_threads\" is invalid, " \ "value: %d < 0!", __LINE__, \ g_disk_writer_threads); result = EINVAL; break; } if (g_disk_rw_separated) { if (g_disk_reader_threads == 0) { logError("file: "__FILE__", line: %d, " \ "item \"disk_reader_threads\" is " \ "invalid, value = 0!", __LINE__); result = EINVAL; break; } if (g_disk_writer_threads == 0) { logError("file: "__FILE__", line: %d, " \ "item \"disk_writer_threads\" is " \ "invalid, value = 0!", __LINE__); result = EINVAL; break; } } else if (g_disk_reader_threads + g_disk_writer_threads == 0) { logError("file: "__FILE__", line: %d, " \ "item \"disk_reader_threads\" and " \ "\"disk_writer_threads\" are " \ "invalid, both value = 0!", __LINE__); result = EINVAL; break; } /* g_disk_rw_direct = iniGetBoolValue(NULL, \ "disk_rw_direct", &iniContext, false); */ pRunByGroup = iniGetStrValue(NULL, "run_by_group", &iniContext); pRunByUser = iniGetStrValue(NULL, "run_by_user", &iniContext); if (pRunByGroup == NULL) { *g_run_by_group = '\0'; } else { snprintf(g_run_by_group, sizeof(g_run_by_group), \ "%s", pRunByGroup); } if (*g_run_by_group == '\0') { g_run_by_gid = getegid(); } else { struct group *pGroup; pGroup = getgrnam(g_run_by_group); if (pGroup == NULL) { result = errno != 0 ? errno : ENOENT; logError("file: "__FILE__", line: %d, " \ "getgrnam fail, errno: %d, " \ "error info: %s", __LINE__, \ result, STRERROR(result)); return result; } g_run_by_gid = pGroup->gr_gid; } if (pRunByUser == NULL) { *g_run_by_user = '******'; } else { snprintf(g_run_by_user, sizeof(g_run_by_user), \ "%s", pRunByUser); } if (*g_run_by_user == '\0') { g_run_by_uid = geteuid(); } else { struct passwd *pUser; pUser = getpwnam(g_run_by_user); if (pUser == NULL) { result = errno != 0 ? errno : ENOENT; logError("file: "__FILE__", line: %d, " \ "getpwnam fail, errno: %d, " \ "error info: %s", __LINE__, \ result, STRERROR(result)); return result; } g_run_by_uid = pUser->pw_uid; } if ((result=load_allow_hosts(&iniContext, \ &g_allow_ip_addrs, &g_allow_ip_count)) != 0) { return result; } g_file_distribute_path_mode = iniGetIntValue(NULL, \ "file_distribute_path_mode", &iniContext, \ FDFS_FILE_DIST_PATH_ROUND_ROBIN); g_file_distribute_rotate_count = iniGetIntValue(NULL, \ "file_distribute_rotate_count", &iniContext, \ FDFS_FILE_DIST_DEFAULT_ROTATE_COUNT); if (g_file_distribute_rotate_count <= 0) { g_file_distribute_rotate_count = \ FDFS_FILE_DIST_DEFAULT_ROTATE_COUNT; } pFsyncAfterWrittenBytes = iniGetStrValue(NULL, \ "fsync_after_written_bytes", &iniContext); if (pFsyncAfterWrittenBytes == NULL) { fsync_after_written_bytes = 0; } else if ((result=parse_bytes(pFsyncAfterWrittenBytes, 1, \ &fsync_after_written_bytes)) != 0) { return result; } g_fsync_after_written_bytes = fsync_after_written_bytes; g_sync_log_buff_interval = iniGetIntValue(NULL, \ "sync_log_buff_interval", &iniContext, \ SYNC_LOG_BUFF_DEF_INTERVAL); if (g_sync_log_buff_interval <= 0) { g_sync_log_buff_interval = SYNC_LOG_BUFF_DEF_INTERVAL; } g_sync_binlog_buff_interval = iniGetIntValue(NULL, \ "sync_binlog_buff_interval", &iniContext,\ SYNC_BINLOG_BUFF_DEF_INTERVAL); if (g_sync_binlog_buff_interval <= 0) { g_sync_binlog_buff_interval=SYNC_BINLOG_BUFF_DEF_INTERVAL; } g_write_mark_file_freq = iniGetIntValue(NULL, \ "write_mark_file_freq", &iniContext, \ FDFS_DEFAULT_SYNC_MARK_FILE_FREQ); if (g_write_mark_file_freq <= 0) { g_write_mark_file_freq = FDFS_DEFAULT_SYNC_MARK_FILE_FREQ; } g_sync_stat_file_interval = iniGetIntValue(NULL, \ "sync_stat_file_interval", &iniContext, \ DEFAULT_SYNC_STAT_FILE_INTERVAL); if (g_sync_stat_file_interval <= 0) { g_sync_stat_file_interval=DEFAULT_SYNC_STAT_FILE_INTERVAL; } pThreadStackSize = iniGetStrValue(NULL, \ "thread_stack_size", &iniContext); if (pThreadStackSize == NULL) { thread_stack_size = 512 * 1024; } else if ((result=parse_bytes(pThreadStackSize, 1, \ &thread_stack_size)) != 0) { return result; } g_thread_stack_size = (int)thread_stack_size; if (g_thread_stack_size < 64 * 1024) { logError("file: "__FILE__", line: %d, " \ "item \"thread_stack_size\" %d is invalid, " \ "which < %d", __LINE__, g_thread_stack_size, \ 64 * 1024); result = EINVAL; break; } g_upload_priority = iniGetIntValue(NULL, \ "upload_priority", &iniContext, \ DEFAULT_UPLOAD_PRIORITY); pIfAliasPrefix = iniGetStrValue(NULL, \ "if_alias_prefix", &iniContext); if (pIfAliasPrefix == NULL) { *g_if_alias_prefix = '\0'; } else { snprintf(g_if_alias_prefix, sizeof(g_if_alias_prefix), "%s", pIfAliasPrefix); } g_check_file_duplicate = iniGetBoolValue(NULL, \ "check_file_duplicate", &iniContext, false); if (g_check_file_duplicate) { char *pKeyNamespace; strcpy(g_fdht_base_path, g_fdfs_base_path); g_fdht_connect_timeout = g_fdfs_connect_timeout; g_fdht_network_timeout = g_fdfs_network_timeout; pKeyNamespace = iniGetStrValue(NULL, \ "key_namespace", &iniContext); if (pKeyNamespace == NULL || *pKeyNamespace == '\0') { logError("file: "__FILE__", line: %d, " \ "item \"key_namespace\" does not " \ "exist or is empty", __LINE__); result = EINVAL; break; } g_namespace_len = strlen(pKeyNamespace); if (g_namespace_len >= sizeof(g_key_namespace)) { g_namespace_len = sizeof(g_key_namespace) - 1; } memcpy(g_key_namespace, pKeyNamespace, g_namespace_len); *(g_key_namespace + g_namespace_len) = '\0'; if ((result=fdht_load_groups(&iniContext, \ &g_group_array)) != 0) { break; } g_keep_alive = iniGetBoolValue(NULL, "keep_alive", \ &iniContext, false); } g_http_port = iniGetIntValue(NULL, "http.server_port", \ &iniContext, 80); if (g_http_port <= 0) { logError("file: "__FILE__", line: %d, " \ "invalid param \"http.server_port\": %d", \ __LINE__, g_http_port); return EINVAL; } pHttpDomain = iniGetStrValue(NULL, \ "http.domain_name", &iniContext); if (pHttpDomain == NULL) { *g_http_domain = '\0'; } else { snprintf(g_http_domain, sizeof(g_http_domain), \ "%s", pHttpDomain); } #ifdef WITH_HTTPD { char *pHttpTrunkSize; int64_t http_trunk_size; if ((result=fdfs_http_params_load(&iniContext, \ filename, &g_http_params)) != 0) { break; } pHttpTrunkSize = iniGetStrValue(NULL, \ "http.trunk_size", &iniContext); if (pHttpTrunkSize == NULL) { http_trunk_size = 64 * 1024; } else if ((result=parse_bytes(pHttpTrunkSize, 1, \ &http_trunk_size)) != 0) { break; } g_http_trunk_size = (int)http_trunk_size; } #endif logInfo("FastDFS v%d.%02d, base_path=%s, store_path_count=%d, " \ "subdir_count_per_path=%d, group_name=%s, " \ "run_by_group=%s, run_by_user=%s, " \ "connect_timeout=%ds, network_timeout=%ds, "\ "port=%d, bind_addr=%s, client_bind=%d, " \ "max_connections=%d, work_threads=%d, " \ "disk_rw_separated=%d, disk_reader_threads=%d, " \ "disk_writer_threads=%d, " \ "buff_size=%dKB, heart_beat_interval=%ds, " \ "stat_report_interval=%ds, tracker_server_count=%d, " \ "sync_wait_msec=%dms, sync_interval=%dms, " \ "sync_start_time=%02d:%02d, sync_end_time=%02d:%02d, "\ "write_mark_file_freq=%d, " \ "allow_ip_count=%d, " \ "file_distribute_path_mode=%d, " \ "file_distribute_rotate_count=%d, " \ "fsync_after_written_bytes=%d, " \ "sync_log_buff_interval=%ds, " \ "sync_binlog_buff_interval=%ds, " \ "sync_stat_file_interval=%ds, " \ "thread_stack_size=%d KB, upload_priority=%d, " \ "if_alias_prefix=%s, " \ "check_file_duplicate=%d, FDHT group count=%d, " \ "FDHT server count=%d, FDHT key_namespace=%s, " \ "FDHT keep_alive=%d, HTTP server port=%d, " \ "domain name=%s", \ g_fdfs_version.major, g_fdfs_version.minor, \ g_fdfs_base_path, g_fdfs_path_count, g_subdir_count_per_path,\ g_group_name, g_run_by_group, g_run_by_user, \ g_fdfs_connect_timeout, \ g_fdfs_network_timeout, g_server_port, bind_addr, \ g_client_bind_addr, g_max_connections, \ g_work_threads, g_disk_rw_separated, \ g_disk_reader_threads, g_disk_writer_threads, \ g_buff_size / 1024, \ g_heart_beat_interval, g_stat_report_interval, \ g_tracker_group.server_count, g_sync_wait_usec / 1000, \ g_sync_interval / 1000, \ g_sync_start_time.hour, g_sync_start_time.minute, \ g_sync_end_time.hour, g_sync_end_time.minute, \ g_write_mark_file_freq, \ g_allow_ip_count, g_file_distribute_path_mode, \ g_file_distribute_rotate_count, \ g_fsync_after_written_bytes, g_sync_log_buff_interval, \ g_sync_binlog_buff_interval, g_sync_stat_file_interval, \ g_thread_stack_size/1024, g_upload_priority, \ g_if_alias_prefix, g_check_file_duplicate, \ g_group_array.group_count, g_group_array.server_count, \ g_key_namespace, g_keep_alive, \ g_http_port, g_http_domain); #ifdef WITH_HTTPD if (!g_http_params.disabled) { logInfo("HTTP supported: " \ "server_port=%d, " \ "http_trunk_size=%d, " \ "default_content_type=%s, " \ "anti_steal_token=%d, " \ "token_ttl=%ds, " \ "anti_steal_secret_key length=%d, " \ "token_check_fail content_type=%s, " \ "token_check_fail buff length=%d", \ g_http_params.server_port, \ g_http_trunk_size, \ g_http_params.default_content_type, \ g_http_params.anti_steal_token, \ g_http_params.token_ttl, \ g_http_params.anti_steal_secret_key.length, \ g_http_params.token_check_fail_content_type, \ g_http_params.token_check_fail_buff.length); } #endif } while (0); iniFreeContext(&iniContext); if (result != 0) { return result; } if ((result=storage_get_my_tracker_client_ip()) != 0) { return result; } if ((result=storage_check_and_make_data_dirs()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "storage_check_and_make_data_dirs fail, " \ "program exit!", __LINE__); return result; } if ((result=storage_get_params_from_tracker()) != 0) { return result; } if ((result=storage_check_ip_changed()) != 0) { return result; } if ((result=init_pthread_lock(&sync_stat_file_lock)) != 0) { return result; } return storage_open_stat_file(); }
int trunk_sync_init() { char data_path[MAX_PATH_SIZE]; char sync_path[MAX_PATH_SIZE]; char binlog_filename[MAX_PATH_SIZE]; int result; snprintf(data_path, sizeof(data_path), "%s/data", g_fdfs_base_path); if (!fileExists(data_path)) { if (mkdir(data_path, 0755) != 0) { logError("file: "__FILE__", line: %d, " \ "mkdir \"%s\" fail, " \ "errno: %d, error info: %s", \ __LINE__, data_path, \ errno, STRERROR(errno)); return errno != 0 ? errno : ENOENT; } STORAGE_CHOWN(data_path, geteuid(), getegid()) } snprintf(sync_path, sizeof(sync_path), \ "%s/"TRUNK_DIR_NAME, data_path); if (!fileExists(sync_path)) { if (mkdir(sync_path, 0755) != 0) { logError("file: "__FILE__", line: %d, " \ "mkdir \"%s\" fail, " \ "errno: %d, error info: %s", \ __LINE__, sync_path, \ errno, STRERROR(errno)); return errno != 0 ? errno : ENOENT; } STORAGE_CHOWN(sync_path, geteuid(), getegid()) } trunk_binlog_write_cache_buff = (char *)malloc( \ TRUNK_BINLOG_BUFFER_SIZE); if (trunk_binlog_write_cache_buff == NULL) { logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, " \ "errno: %d, error info: %s", \ __LINE__, TRUNK_BINLOG_BUFFER_SIZE, \ errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } get_trunk_binlog_filename(binlog_filename); if ((result=trunk_binlog_open_writer(binlog_filename)) != 0) { return result; } if ((result=init_pthread_lock(&trunk_sync_thread_lock)) != 0) { return result; } STORAGE_FCHOWN(trunk_binlog_fd, binlog_filename, geteuid(), getegid()) return 0; }
ConnectionInfo *conn_pool_get_connection(ConnectionPool *cp, const ConnectionInfo *conn, int *err_no) { char key[32]; int key_len; int bytes; char *p; ConnectionManager *cm; ConnectionNode *node; ConnectionInfo *ci; time_t current_time; *err_no = conn_pool_get_key(conn, key, &key_len); if (*err_no != 0) { return NULL; } pthread_mutex_lock(&cp->lock); cm = (ConnectionManager *)hash_find(&cp->hash_array, key, key_len); if (cm == NULL) { cm = (ConnectionManager *)malloc(sizeof(ConnectionManager)); if (cm == NULL) { *err_no = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, errno: %d, " \ "error info: %s", __LINE__, \ (int)sizeof(ConnectionManager), \ *err_no, STRERROR(*err_no)); pthread_mutex_unlock(&cp->lock); return NULL; } cm->head = NULL; cm->total_count = 0; cm->free_count = 0; if ((*err_no=init_pthread_lock(&cm->lock)) != 0) { pthread_mutex_unlock(&cp->lock); return NULL; } hash_insert(&cp->hash_array, key, key_len, cm); } pthread_mutex_unlock(&cp->lock); current_time = get_current_time(); pthread_mutex_lock(&cm->lock); while (1) { if (cm->head == NULL) { if ((cp->max_count_per_entry > 0) && (cm->total_count >= cp->max_count_per_entry)) { *err_no = ENOSPC; logError("file: "__FILE__", line: %d, " \ "connections: %d of server %s:%d " \ "exceed limit: %d", __LINE__, \ cm->total_count, conn->ip_addr, \ conn->port, cp->max_count_per_entry); pthread_mutex_unlock(&cm->lock); return NULL; } bytes = sizeof(ConnectionNode) + sizeof(ConnectionInfo); p = (char *)malloc(bytes); if (p == NULL) { *err_no = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, errno: %d, " \ "error info: %s", __LINE__, \ bytes, *err_no, STRERROR(*err_no)); pthread_mutex_unlock(&cm->lock); return NULL; } node = (ConnectionNode *)p; node->conn = (ConnectionInfo *)(p + sizeof(ConnectionNode)); node->manager = cm; node->next = NULL; node->atime = 0; cm->total_count++; pthread_mutex_unlock(&cm->lock); memcpy(node->conn, conn, sizeof(ConnectionInfo)); node->conn->sock = -1; *err_no = conn_pool_connect_server(node->conn, \ cp->connect_timeout); if (*err_no != 0) { pthread_mutex_lock(&cm->lock); cm->total_count--; //rollback pthread_mutex_unlock(&cm->lock); free(p); return NULL; } logDebug("file: "__FILE__", line: %d, " \ "server %s:%d, new connection: %d, " \ "total_count: %d, free_count: %d", \ __LINE__, conn->ip_addr, conn->port, \ node->conn->sock, cm->total_count, \ cm->free_count); return node->conn; } else { node = cm->head; ci = node->conn; cm->head = node->next; cm->free_count--; if (current_time - node->atime > cp->max_idle_time) { cm->total_count--; logDebug("file: "__FILE__", line: %d, " \ "server %s:%d, connection: %d idle " \ "time: %d exceeds max idle time: %d, "\ "total_count: %d, free_count: %d", \ __LINE__, conn->ip_addr, conn->port, \ ci->sock, \ (int)(current_time - node->atime), \ cp->max_idle_time, cm->total_count, \ cm->free_count); conn_pool_disconnect_server(ci); free(node); continue; } pthread_mutex_unlock(&cm->lock); logDebug("file: "__FILE__", line: %d, " \ "server %s:%d, reuse connection: %d, " \ "total_count: %d, free_count: %d", __LINE__, conn->ip_addr, conn->port, ci->sock, cm->total_count, cm->free_count); return ci; } } }
int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name, const int element_size, const int alloc_elements_once, fast_mblock_alloc_init_func init_func, const bool need_lock, fast_mblock_malloc_trunk_check_func malloc_trunk_check, fast_mblock_malloc_trunk_notify_func malloc_trunk_notify, void *malloc_trunk_args) { int result; int block_size; if (element_size <= 0) { /*logError("file: "__FILE__", line: %d, " \ "invalid block size: %d", \ __LINE__, element_size);*/ return EINVAL; } mblock->info.element_size = MEM_ALIGN(element_size); block_size = fast_mblock_get_block_size(mblock); if (alloc_elements_once > 0) { mblock->alloc_elements_once = alloc_elements_once; } else { mblock->alloc_elements_once = (1024 * 1024) / block_size; } if (need_lock && (result=init_pthread_lock(&(mblock->lock))) != 0) { /*logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result));*/ return result; } mblock->alloc_init_func = init_func; INIT_HEAD(&mblock->trunks.head); mblock->info.trunk_total_count = 0; mblock->info.trunk_used_count = 0; mblock->free_chain_head = NULL; mblock->delay_free_chain.head = NULL; mblock->delay_free_chain.tail = NULL; mblock->info.element_total_count = 0; mblock->info.element_used_count = 0; mblock->info.instance_count = 1; mblock->info.trunk_size = sizeof(struct fast_mblock_malloc) + block_size * mblock->alloc_elements_once; mblock->need_lock = need_lock; mblock->malloc_trunk_callback.check_func = malloc_trunk_check; mblock->malloc_trunk_callback.notify_func = malloc_trunk_notify; mblock->malloc_trunk_callback.args = malloc_trunk_args; if (name != NULL) { snprintf(mblock->info.name, sizeof(mblock->info.name), "%s", name); } else { *mblock->info.name = '\0'; } add_to_mblock_list(mblock); return 0; }
int storage_trunk_init() { int result; if (!g_if_trunker_self) { logError("file: "__FILE__", line: %d, " \ "I am not trunk server!", __LINE__); return 0; } if (trunk_init_flag != STORAGE_TRUNK_INIT_FLAG_NONE) { logWarning("file: "__FILE__", line: %d, " \ "trunk already inited!", __LINE__); return 0; } logDebug("file: "__FILE__", line: %d, " \ "storage trunk init ...", __LINE__); g_trunk_server.sock = -1; g_trunk_server.port = g_server_port; if ((result=init_pthread_lock(&trunk_file_lock)) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } if ((result=init_pthread_lock(&trunk_mem_lock)) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } if ((result=fast_mblock_init(&free_blocks_man, \ sizeof(FDFSTrunkNode), 0)) != 0) { return result; } if ((result=fast_mblock_init(&tree_nodes_man, \ sizeof(FDFSTrunkSlot), 0)) != 0) { return result; } if ((result=avl_tree_init(&tree_info_by_size, NULL, \ storage_trunk_node_compare_size)) != 0) { logError("file: "__FILE__", line: %d, " \ "avl_tree_init fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } if ((result=trunk_free_block_checker_init()) != 0) { return result; } if ((result=storage_trunk_load()) != 0) { return result; } logInfo("file: "__FILE__", line: %d, " \ "tree by space size node count: %d, tree by trunk file id " \ "node count: %d, free block count: %d, " \ "trunk_total_free_space: "INT64_PRINTF_FORMAT, __LINE__, \ avl_tree_count(&tree_info_by_size), \ trunk_free_block_tree_node_count(), \ trunk_free_block_total_count(), \ g_trunk_total_free_space); /* { char filename[MAX_PATH_SIZE]; sprintf(filename, "%s/logs/tttt.dat", g_fdfs_base_path); trunk_free_block_tree_print(filename); } */ trunk_init_flag = STORAGE_TRUNK_INIT_FLAG_DONE; return 0; }
int free_queue_init_ex(const int max_connections, const int init_connections, const int alloc_task_once, const int min_buff_size, const int max_buff_size, const int arg_size) { #define MAX_DATA_SIZE (256 * 1024 * 1024) int64_t total_size; struct mpool_node *mpool; int alloc_size; int alloc_once; int result; int loop_count; int aligned_min_size; int aligned_max_size; int aligned_arg_size; rlim_t max_data_size; if ((result=init_pthread_lock(&(g_free_queue.lock))) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_lock fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } aligned_min_size = MEM_ALIGN(min_buff_size); aligned_max_size = MEM_ALIGN(max_buff_size); aligned_arg_size = MEM_ALIGN(arg_size); g_free_queue.block_size = ALIGNED_TASK_INFO_SIZE + aligned_arg_size; alloc_size = g_free_queue.block_size * init_connections; if (aligned_max_size > aligned_min_size) { total_size = alloc_size; g_free_queue.malloc_whole_block = false; max_data_size = 0; } else { struct rlimit rlimit_data; if (getrlimit(RLIMIT_DATA, &rlimit_data) < 0) { logError("file: "__FILE__", line: %d, " \ "call getrlimit fail, " \ "errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); return errno != 0 ? errno : EPERM; } if (rlimit_data.rlim_cur == RLIM_INFINITY) { max_data_size = MAX_DATA_SIZE; } else { max_data_size = rlimit_data.rlim_cur; if (max_data_size > MAX_DATA_SIZE) { max_data_size = MAX_DATA_SIZE; } } if (max_data_size >= (int64_t)(g_free_queue.block_size + aligned_min_size) * (int64_t)init_connections) { total_size = alloc_size + (int64_t)aligned_min_size * init_connections; g_free_queue.malloc_whole_block = true; g_free_queue.block_size += aligned_min_size; } else { total_size = alloc_size; g_free_queue.malloc_whole_block = false; max_data_size = 0; } } g_free_queue.max_connections = max_connections; g_free_queue.alloc_connections = init_connections; if (alloc_task_once <= 0) { g_free_queue.alloc_task_once = 256; alloc_once = MAX_DATA_SIZE / g_free_queue.block_size; if (g_free_queue.alloc_task_once > alloc_once) { g_free_queue.alloc_task_once = alloc_once; } } else { g_free_queue.alloc_task_once = alloc_task_once; } g_free_queue.min_buff_size = aligned_min_size; g_free_queue.max_buff_size = aligned_max_size; g_free_queue.arg_size = aligned_arg_size; logDebug("file: "__FILE__", line: %d, " "max_connections: %d, init_connections: %d, alloc_task_once: %d, " "min_buff_size: %d, max_buff_size: %d, block_size: %d, " "arg_size: %d, max_data_size: %d, total_size: %"PRId64, __LINE__, max_connections, init_connections, g_free_queue.alloc_task_once, aligned_min_size, aligned_max_size, g_free_queue.block_size, aligned_arg_size, (int)max_data_size, total_size); if ((!g_free_queue.malloc_whole_block) || (total_size <= max_data_size)) { loop_count = 1; mpool = malloc_mpool(total_size); if (mpool == NULL) { return errno != 0 ? errno : ENOMEM; } g_mpool.head = mpool; g_mpool.tail = mpool; } else { int remain_count; int alloc_count; int current_alloc_size; loop_count = 0; remain_count = init_connections; alloc_once = max_data_size / g_free_queue.block_size; while (remain_count > 0) { alloc_count = (remain_count > alloc_once) ? alloc_once : remain_count; current_alloc_size = g_free_queue.block_size * alloc_count; mpool = malloc_mpool(current_alloc_size); if (mpool == NULL) { free_queue_destroy(); return errno != 0 ? errno : ENOMEM; } if (g_mpool.tail == NULL) { g_mpool.head = mpool; } else { g_mpool.tail->next = mpool; g_mpool.tail->last_block->next = mpool->blocks; //link previous mpool to current } g_mpool.tail = mpool; remain_count -= alloc_count; loop_count++; } logDebug("file: "__FILE__", line: %d, " \ "alloc_once: %d", __LINE__, alloc_once); } logDebug("file: "__FILE__", line: %d, " \ "malloc task info as whole: %d, malloc loop count: %d", \ __LINE__, g_free_queue.malloc_whole_block, loop_count); if (g_mpool.head != NULL) { g_free_queue.head = g_mpool.head->blocks; g_free_queue.tail = g_mpool.tail->last_block; } return 0; }
int sched_start_ex(ScheduleArray *pScheduleArray, pthread_t *ptid, const int stack_size, bool * volatile pcontinue_flag, ScheduleContext **ppContext) { int result; pthread_attr_t thread_attr; ScheduleContext *pContext; pContext = (ScheduleContext *)malloc(sizeof(ScheduleContext)); if (pContext == NULL) { result = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "malloc %d bytes failed, " \ "errno: %d, error info: %s", \ __LINE__, (int)sizeof(ScheduleContext), \ result, STRERROR(result)); return result; } memset(pContext, 0, sizeof(ScheduleContext)); if ((result=init_pthread_attr(&thread_attr, stack_size)) != 0) { free(pContext); return result; } if ((result=sched_dup_array(pScheduleArray, \ &(pContext->scheduleArray))) != 0) { free(pContext); return result; } if (timer_slot_count > 0) { if ((result=fast_mblock_init(&pContext->mblock, sizeof(FastDelayTask), mblock_alloc_once)) != 0) { free(pContext); return result; } g_current_time = time(NULL); if ((result=fast_timer_init(&pContext->timer, timer_slot_count, g_current_time)) != 0) { free(pContext); return result; } if ((result=init_pthread_lock(&pContext->delay_queue.lock)) != 0) { free(pContext); return result; } pContext->timer_init = true; } pContext->pcontinue_flag = pcontinue_flag; if ((result=pthread_create(ptid, &thread_attr, \ sched_thread_entrance, pContext)) != 0) { free(pContext); logError("file: "__FILE__", line: %d, " \ "create thread failed, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); } *ppContext = pContext; pthread_attr_destroy(&thread_attr); return result; }
int storage_dio_init() { int result; int bytes; int threads_count_per_path; int context_count; struct storage_dio_thread_data *pThreadData; struct storage_dio_thread_data *pDataEnd; struct storage_dio_context *pContext; struct storage_dio_context *pContextEnd; pthread_t tid; pthread_attr_t thread_attr; if ((result=init_pthread_lock(&g_dio_thread_lock)) != 0) { return result; } if ((result=init_pthread_attr(&thread_attr, g_thread_stack_size)) != 0) { logError("file: "__FILE__", line: %d, " \ "init_pthread_attr fail, program exit!", __LINE__); return result; } bytes = sizeof(struct storage_dio_thread_data) * g_fdfs_store_paths.count; g_dio_thread_data = (struct storage_dio_thread_data *)malloc(bytes); if (g_dio_thread_data == NULL) { logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, errno: %d, error info: %s", \ __LINE__, bytes, errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } memset(g_dio_thread_data, 0, bytes); threads_count_per_path = g_disk_reader_threads + g_disk_writer_threads; context_count = threads_count_per_path * g_fdfs_store_paths.count; bytes = sizeof(struct storage_dio_context) * context_count; g_dio_contexts = (struct storage_dio_context *)malloc(bytes); if (g_dio_contexts == NULL) { logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, " \ "errno: %d, error info: %s", __LINE__, \ bytes, errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } memset(g_dio_contexts, 0, bytes); g_dio_thread_count = 0; pDataEnd = g_dio_thread_data + g_fdfs_store_paths.count; for (pThreadData=g_dio_thread_data; pThreadData<pDataEnd; pThreadData++) { pThreadData->count = threads_count_per_path; pThreadData->contexts = g_dio_contexts + (pThreadData - \ g_dio_thread_data) * threads_count_per_path; pThreadData->reader = pThreadData->contexts; pThreadData->writer = pThreadData->contexts+g_disk_reader_threads; pContextEnd = pThreadData->contexts + pThreadData->count; for (pContext=pThreadData->contexts; pContext<pContextEnd; \ pContext++) { if ((result=blocked_queue_init(&(pContext->queue))) != 0) { return result; } if ((result=pthread_create(&tid, &thread_attr, \ dio_thread_entrance, pContext)) != 0) { logError("file: "__FILE__", line: %d, " \ "create thread failed, " \ "startup threads: %d, " \ "errno: %d, error info: %s", \ __LINE__, g_dio_thread_count, \ result, STRERROR(result)); return result; } else { pthread_mutex_lock(&g_dio_thread_lock); g_dio_thread_count++; pthread_mutex_unlock(&g_dio_thread_lock); } } } pthread_attr_destroy(&thread_attr); return result; }