static void launch_read_stream_thread(shout_context_t *context) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; int sanity = 10; size_t used; context->thread_running = 1; switch_threadattr_create(&thd_attr, context->memory_pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, read_stream_thread, context, context->memory_pool); while (context->thread_running && --sanity) { /* at least 1s of audio and up to 5s initialize */ switch_mutex_lock(context->audio_mutex); used = switch_buffer_inuse(context->audio_buffer); switch_mutex_unlock(context->audio_mutex); if (used >= (2 * context->samplerate)) { break; } switch_yield(500000); } }
/** * Create a new graylog2 delivery thread * @param pool to use */ static void start_deliver_graylog2_thread(switch_memory_pool_t *pool) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; switch_threadattr_create(&thd_attr, pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, deliver_graylog2_thread, NULL, pool); }
static void launch_modem_thread(modem_t *modem) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; switch_threadattr_create(&thd_attr, globals.pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, modem_thread, modem, globals.pool); }
SWITCH_DECLARE(void) switch_scheduler_task_thread_start(void) { switch_threadattr_t *thd_attr; switch_core_new_memory_pool(&globals.memory_pool); switch_threadattr_create(&thd_attr, globals.memory_pool); switch_mutex_init(&globals.task_mutex, SWITCH_MUTEX_NESTED, globals.memory_pool); switch_threadattr_detach_set(thd_attr, 1); switch_thread_create(&task_thread_p, thd_attr, switch_scheduler_task_thread, NULL, globals.memory_pool); }
SWITCH_DECLARE(void) switch_nat_thread_start(void) { switch_threadattr_t *thd_attr; if (init_nat_monitor(nat_globals_perm.pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to initialize NAT thread\n"); return; } switch_threadattr_create(&thd_attr, nat_globals_perm.pool); switch_threadattr_detach_set(thd_attr, 1); switch_thread_create(&nat_thread_p, thd_attr, switch_nat_multicast_runtime, NULL, nat_globals_perm.pool); }
bool AsyncIOServer::Start( switch_memory_pool_t *pool, int iThreadCount, const char *ip, switch_port_t port ) { bool bFlag = false; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AsyncIOServer::Start( " "iThreadCount : %d, " "ip : %s, " "port : %d " ") \n", iThreadCount, ip, port ); mRunning = true; mpPool = pool; mThreadCount = iThreadCount; // 创建处理队列 switch_queue_create(&mpHandleQueue, SWITCH_CORE_QUEUE_LEN, mpPool); // 创建处理线程 switch_threadattr_t *thd_handle_attr = NULL; switch_threadattr_create(&thd_handle_attr, mpPool); switch_threadattr_detach_set(thd_handle_attr, 1); switch_threadattr_stacksize_set(thd_handle_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_priority_set(thd_handle_attr, SWITCH_PRI_IMPORTANT); mpHandleThreads = (switch_thread_t**)switch_core_alloc(mpPool, mThreadCount * sizeof(switch_thread_t*)); for(int i = 0; i < mThreadCount; i++) { switch_thread_create(&mpHandleThreads[i], thd_handle_attr, ws_handle_thread, this, mpPool); } // 开始监听socket bFlag = mTcpServer.Start(mpPool, ip, port); if( bFlag ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AsyncIOServer::Start( success ) \n"); } else { Stop(); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AsyncIOServer::Start( fail ) \n"); } return bFlag; }
static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char api_cmd[MAXATOMLEN]; char arg[ARGLEN]; if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string_or_binary(buf->buff, &buf->index, ARGLEN - 1, arg)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { struct api_command_struct *acs = NULL; switch_memory_pool_t *pool; switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; switch_uuid_t uuid; switch_core_new_memory_pool(&pool); acs = switch_core_alloc(pool, sizeof(*acs)); switch_assert(acs); acs->pool = pool; acs->listener = listener; acs->api_cmd = switch_core_strdup(acs->pool, api_cmd); acs->arg = switch_core_strdup(acs->pool, arg); acs->bg = 1; acs->pid = msg->from; switch_threadattr_create(&thd_attr, acs->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_uuid_get(&uuid); switch_uuid_format(acs->uuid_str, &uuid); switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool); ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "ok"); _ei_x_encode_string(rbuf, acs->uuid_str); } return SWITCH_STATUS_SUCCESS; }
static void launch_write_stream_thread(shout_context_t *context) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; int sanity = 10; if (context->err) { return; } context->thread_running = 1; switch_threadattr_create(&thd_attr, context->memory_pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, write_stream_thread, context, context->memory_pool); while (context->thread_running && context->thread_running != 2) { switch_yield(100000); if (!--sanity) break; } }
SWITCH_DECLARE(switch_status_t) switch_log_init(switch_memory_pool_t *pool, switch_bool_t colorize) { switch_threadattr_t *thd_attr;; switch_assert(pool != NULL); LOG_POOL = pool; switch_threadattr_create(&thd_attr, LOG_POOL); switch_threadattr_detach_set(thd_attr, 1); switch_queue_create(&LOG_QUEUE, SWITCH_CORE_QUEUE_LEN, LOG_POOL); #ifdef SWITCH_LOG_RECYCLE switch_queue_create(&LOG_RECYCLE_QUEUE, SWITCH_CORE_QUEUE_LEN, LOG_POOL); #endif switch_mutex_init(&BINDLOCK, SWITCH_MUTEX_NESTED, LOG_POOL); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, log_thread, NULL, LOG_POOL); while (!THREAD_RUNNING) { switch_cond_next(); } if (colorize) { #ifdef WIN32 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (switch_core_get_console() == stdout && hStdout != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) { wOldColorAttrs = csbiInfo.wAttributes; COLORIZE = SWITCH_TRUE; } #else COLORIZE = SWITCH_TRUE; #endif } return SWITCH_STATUS_SUCCESS; }
int py_thread(const char *text) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; switch_memory_pool_t *pool; struct switch_py_thread *pt; switch_core_new_memory_pool(&pool); assert(pool != NULL); pt = switch_core_alloc(pool, sizeof(*pt)); assert(pt != NULL); pt->pool = pool; pt->args = switch_core_strdup(pt->pool, text); switch_threadattr_create(&thd_attr, pt->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, py_thread_run, pt, pt->pool); return 0; }
static int task_thread_loop(int done) { switch_scheduler_task_container_t *tofree, *tp, *last = NULL; switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp; tp = tp->next) { if (done) { tp->destroyed = 1; } else if (!tp->destroyed) { int64_t now = switch_epoch_time_now(NULL); if (now >= tp->task.runtime && !tp->in_thread) { int32_t diff = (int32_t) (now - tp->task.runtime); if (diff > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n", diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group)); } tp->executed = now; if (switch_test_flag(tp, SSHF_OWN_THREAD)) { switch_thread_t *thread; switch_threadattr_t *thd_attr; switch_core_new_memory_pool(&tp->pool); switch_threadattr_create(&thd_attr, tp->pool); switch_threadattr_detach_set(thd_attr, 1); tp->in_thread = 1; switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool); } else { tp->running = 1; switch_mutex_unlock(globals.task_mutex); switch_scheduler_execute(tp); switch_mutex_lock(globals.task_mutex); tp->running = 0; } } } } switch_mutex_unlock(globals.task_mutex); switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp;) { if (tp->destroyed && !tp->in_thread) { switch_event_t *event; tofree = tp; tp = tp->next; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n", tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group)); if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tofree->task.task_id); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tofree->desc); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Group", switch_str_nil(tofree->task.group)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tofree->task.runtime); switch_queue_push(globals.event_queue, event); event = NULL; } if (last) { last->next = tofree->next; } else { globals.task_list = tofree->next; } switch_safe_free(tofree->task.group); if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) { free(tofree->task.cmd_arg); } switch_safe_free(tofree->desc); free(tofree); } else { last = tp; tp = tp->next; } } switch_mutex_unlock(globals.task_mutex); return done; }
switch_status_t rtmp_tcp_init(rtmp_profile_t *profile, const char *bindaddr, rtmp_io_t **new_io, switch_memory_pool_t *pool) { char *szport; switch_sockaddr_t *sa; switch_threadattr_t *thd_attr = NULL; rtmp_io_tcp_t *io_tcp; io_tcp = (rtmp_io_tcp_t*)switch_core_alloc(pool, sizeof(rtmp_io_tcp_t)); io_tcp->base.pool = pool; io_tcp->ip = switch_core_strdup(pool, bindaddr); *new_io = (rtmp_io_t*)io_tcp; io_tcp->base.profile = profile; io_tcp->base.read = rtmp_tcp_read; io_tcp->base.write = rtmp_tcp_write; io_tcp->base.close = rtmp_tcp_close; io_tcp->base.name = "tcp"; io_tcp->base.address = switch_core_strdup(pool, io_tcp->ip); if ((szport = strchr(io_tcp->ip, ':'))) { *szport++ = '\0'; io_tcp->port = atoi(szport); } else { io_tcp->port = RTMP_DEFAULT_PORT; } if (switch_sockaddr_info_get(&sa, io_tcp->ip, SWITCH_INET, io_tcp->port, 0, pool)) { goto fail; } if (switch_socket_create(&io_tcp->listen_socket, switch_sockaddr_get_family(sa), SOCK_STREAM, SWITCH_PROTO_TCP, pool)) { goto fail; } if (switch_socket_opt_set(io_tcp->listen_socket, SWITCH_SO_REUSEADDR, 1)) { goto fail; } if (switch_socket_opt_set(io_tcp->listen_socket, SWITCH_SO_TCP_NODELAY, 1)) { goto fail; } if (switch_socket_bind(io_tcp->listen_socket, sa)) { goto fail; } if (switch_socket_listen(io_tcp->listen_socket, 10)) { goto fail; } if (switch_socket_opt_set(io_tcp->listen_socket, SWITCH_SO_NONBLOCK, TRUE)) { goto fail; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Listening on %s:%u (tcp)\n", io_tcp->ip, io_tcp->port); io_tcp->base.running = 1; if (switch_pollset_create(&io_tcp->pollset, 1000 /* max poll fds */, pool, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pollset_create failed\n"); goto fail; } switch_socket_create_pollfd(&(io_tcp->listen_pollfd), io_tcp->listen_socket, SWITCH_POLLIN | SWITCH_POLLERR, NULL, pool); if (switch_pollset_add(io_tcp->pollset, io_tcp->listen_pollfd) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pollset_add failed\n"); goto fail; } switch_mutex_init(&io_tcp->mutex, SWITCH_MUTEX_NESTED, pool); switch_threadattr_create(&thd_attr, pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&io_tcp->thread, thd_attr, rtmp_io_tcp_thread, *new_io, pool); return SWITCH_STATUS_SUCCESS; fail: if (io_tcp->listen_socket) { switch_socket_close(io_tcp->listen_socket); } *new_io = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Socket error. Couldn't listen on %s:%u\n", io_tcp->ip, io_tcp->port); return SWITCH_STATUS_FALSE; }
static void launch_thread(const char *name, const char *path, switch_xml_t directory) { local_stream_source_t *source = NULL; switch_memory_pool_t *pool; switch_xml_t param; switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); abort(); } source = switch_core_alloc(pool, sizeof(*source)); assert(source != NULL); source->pool = pool; source->name = switch_core_strdup(source->pool, name); source->location = switch_core_strdup(source->pool, path); source->rate = 8000; source->interval = 20; source->channels = 1; source->timer_name = "soft"; source->prebuf = DEFAULT_PREBUFFER_SIZE; source->stopped = 0; source->hup = 0; source->chime_freq = 30; for (param = switch_xml_child(directory, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "rate")) { int tmp = atoi(val); if (tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 || tmp == 32000 || tmp == 48000) { source->rate = tmp; } } else if (!strcasecmp(var, "shuffle")) { source->shuffle = switch_true(val); } else if (!strcasecmp(var, "prebuf")) { int tmp = atoi(val); if (tmp > 0) { source->prebuf = (uint32_t) tmp; } } else if (!strcasecmp(var, "channels")) { int tmp = atoi(val); if (tmp == 1 || tmp == 2) { source->channels = (uint8_t) tmp; } } else if (!strcasecmp(var, "chime-freq")) { int tmp = atoi(val); if (tmp > 1) { source->chime_freq = tmp; } } else if (!strcasecmp(var, "chime-max")) { int tmp = atoi(val); if (tmp > 1) { source->chime_max = tmp; } } else if (!strcasecmp(var, "chime-list")) { char *list_dup = switch_core_strdup(source->pool, val); source->chime_total = switch_separate_string(list_dup, ',', source->chime_list, (sizeof(source->chime_list) / sizeof(source->chime_list[0]))); } else if (!strcasecmp(var, "interval")) { int tmp = atoi(val); if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) { source->interval = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Interval must be multiple of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL); } } else if (!strcasecmp(var, "timer-name")) { source->timer_name = switch_core_strdup(source->pool, val); } } if (source->chime_max) { source->chime_max *= source->rate; } if (source->chime_total) { source->chime_counter = source->rate * source->chime_freq; } source->samples = switch_samples_per_packet(source->rate, source->interval); switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool); switch_threadattr_create(&thd_attr, source->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool); }
static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle, const char *path) { portaudio_stream_context_t *context; portaudio_stream_source_t *source; switch_memory_pool_t *pool; switch_status_t status = SWITCH_STATUS_FALSE; switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; uint32_t rate = PREFERRED_RATE; char *npath; int devNumber; int tmp; handle->pre_buffer_datalen = 0; if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing! (yet)\n"); return status; } npath = switch_core_strdup(module_pool, path); tmp = handle->samplerate; if (tmp == 8000 || tmp == 16000 || tmp == 32000 || tmp == 48000) { rate = tmp; } if (*path == '#') { devNumber = get_dev_by_number(npath + 1, 1); } else { devNumber = get_dev_by_name(npath, 1); } npath = switch_mprintf("device-%d at %d", devNumber, rate); switch_mutex_lock(globals.mutex); source = switch_core_hash_find(globals.source_hash, npath); /* dev isnt there, try to start thread */ if (!source) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " source isnt Created, create and start thread!\n"); if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, " :S no pool\n"); } else { source = switch_core_alloc(pool, sizeof(*source)); if (source != NULL) { source->pool = pool; source->sourcedev = devNumber; source->sourcename = switch_core_strdup(source->pool, npath); source->rate = rate; source->interval = 20; source->channels = 1; source->timer_name = "soft"; source->prebuf = DEFAULT_PREBUFFER_SIZE; source->stopped = 0; source->ready = 0; source->samples = switch_samples_per_packet(source->rate, source->interval); switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool); switch_threadattr_create(&thd_attr, source->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool); } } } switch_mutex_unlock(globals.mutex); switch_yield(1000000); /* dev already engaged */ if (source) { /*wait for source to be ready */ while (source->ready == 0) { switch_yield(100000); } if (switch_thread_rwlock_tryrdlock(source->rwlock) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " error rwlock !\n"); source = NULL; } } if (source) { status = SWITCH_STATUS_SUCCESS; if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " error allocating context!\n"); status = SWITCH_STATUS_MEMERR; } else { /* everything goes fine at this point */ handle->samples = 0; handle->samplerate = source->rate; handle->channels = 1; handle->format = 0; handle->sections = 0; handle->seekable = 0; handle->speed = 0; handle->private_info = context; handle->interval = source->interval; switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); status = SWITCH_STATUS_MEMERR; } else { /* context created... then continue */ context->source = source; context->file = handle->file; context->func = handle->func; context->line = handle->line; context->handle = handle; switch_mutex_lock(source->mutex); context->next = source->context_list; source->context_list = context; source->total++; switch_mutex_unlock(source->mutex); } } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown source %s\n", path); status = SWITCH_STATUS_FALSE; } return status; }
switch_memory_pool_t *switch_core_memory_init(void) { #ifndef INSTANTLY_DESTROY_POOLS switch_threadattr_t *thd_attr; #endif #ifdef PER_POOL_LOCK apr_allocator_t *my_allocator = NULL; apr_thread_mutex_t *my_mutex; #endif memset(&memory_manager, 0, sizeof(memory_manager)); #ifdef PER_POOL_LOCK if ((apr_allocator_create(&my_allocator)) != APR_SUCCESS) { abort(); } if ((apr_pool_create_ex(&memory_manager.memory_pool, NULL, NULL, my_allocator)) != APR_SUCCESS) { apr_allocator_destroy(my_allocator); my_allocator = NULL; abort(); } if ((apr_thread_mutex_create(&my_mutex, APR_THREAD_MUTEX_NESTED, memory_manager.memory_pool)) != APR_SUCCESS) { abort(); } apr_allocator_mutex_set(my_allocator, my_mutex); apr_pool_mutex_set(memory_manager.memory_pool, my_mutex); apr_allocator_owner_set(my_allocator, memory_manager.memory_pool); apr_pool_tag(memory_manager.memory_pool, "core_pool"); #else apr_pool_create(&memory_manager.memory_pool, NULL); switch_assert(memory_manager.memory_pool != NULL); #endif #ifdef USE_MEM_LOCK switch_mutex_init(&memory_manager.mem_lock, SWITCH_MUTEX_NESTED, memory_manager.memory_pool); #endif #ifdef INSTANTLY_DESTROY_POOLS { void *foo; foo = (void *) (intptr_t) pool_thread; } #else switch_queue_create(&memory_manager.pool_queue, 50000, memory_manager.memory_pool); switch_queue_create(&memory_manager.pool_recycle_queue, 50000, memory_manager.memory_pool); switch_threadattr_create(&thd_attr, memory_manager.memory_pool); switch_threadattr_detach_set(thd_attr, 0); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&pool_thread_p, thd_attr, pool_thread, NULL, memory_manager.memory_pool); while (!memory_manager.pool_thread_running) { switch_cond_next(); } #endif return memory_manager.memory_pool; }
static int task_thread_loop(int done) { switch_scheduler_task_container_t *tofree, *tp, *last = NULL; switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp; tp = tp->next) { if (done) { tp->destroyed = 1; } else if (!tp->destroyed) { int64_t now = switch_epoch_time_now(NULL); if (now >= tp->task.runtime && !tp->in_thread) { int32_t diff = (int32_t) (now - tp->task.runtime); if (diff > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n", diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group)); } tp->executed = now; if (switch_test_flag(tp, SSHF_OWN_THREAD)) { switch_thread_t *thread; switch_threadattr_t *thd_attr; switch_core_new_memory_pool(&tp->pool); switch_threadattr_create(&thd_attr, tp->pool); switch_threadattr_detach_set(thd_attr, 1); tp->in_thread = 1; switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool); } else { switch_scheduler_execute(tp); } } } } switch_mutex_unlock(globals.task_mutex); switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp;) { if (tp->destroyed && !tp->in_thread) { tofree = tp; tp = tp->next; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n", tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group)); if (last) { last->next = tofree->next; } else { globals.task_list = tofree->next; } switch_safe_free(tofree->task.group); if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) { free(tofree->task.cmd_arg); } switch_safe_free(tofree->desc); free(tofree); } else { last = tp; tp = tp->next; } } switch_mutex_unlock(globals.task_mutex); return done; }