static void * thread_loop (void *args) { struct thread_pool *pool = args; struct work_unit *work; while (NULL != (work = async_queue_pop (pool->work_queue, true))) { if (THREAD_POOL_TERM_SIG == work->func) { pthread_mutex_lock (&pool->lock); if (1 < pool->num_threads) thread_pool_push (pool, THREAD_POOL_TERM_SIG, NULL); pool->num_threads--; pthread_mutex_unlock (&pool->lock); free (work); return NULL; } work->func (work->data); free (work); } return NULL; }
static void __client_writer_cb(struct ev_loop *loop, struct tls_user_context_t *context, int revents) { user_session_t *session; int fd; #if DEBUG_ENABLE int i = 0; #endif while ((fd = GPOINTER_TO_INT(g_async_queue_try_pop(writer_queue)))) { session = get_client_datas_by_socket(fd); if (session == NULL) { continue; } if (g_mutex_trylock(session->rw_lock)) { ev_io_stop(session->srv_context->loop, &session->client_watcher); debug_log_message(VERBOSE_DEBUG, DEBUG_AREA_USER, "sending session to user_workers (%d)", i); g_mutex_unlock(session->rw_lock); thread_pool_push(nuauthdatas->user_workers, session, NULL); } #if DEBUG_ENABLE i++; #endif unlock_client_datas(); } }
void OnTcpConnected(void* param, socket_t sock, const char* ip, int port) { WebSession* session = new WebSession(sock, ip, port); if(0 != thread_pool_push(g_thdpool, WebSession::Run, session)) { printf("thread pool push error[%s.%d].\n", ip, port); delete session; } }
void thread_pool_test(void) { int i, r; thread_pool_t pool; pool = thread_pool_create(4, 2, 8); for(i=0; i<20; i++) { r = thread_pool_push(pool, worker, &i); assert(0 == r); } thread_pool_destroy(pool); }
static void CALLBACK timer_schd_worker(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { timer_context_t* ctx; ctx = (timer_context_t*)dwUser; if(1 != InterlockedIncrement(&ctx->locked)) { InterlockedDecrement(&ctx->locked); } else { // one timer only can be call in one thread thread_pool_push(g_ctx.pool, timer_thread_worker, ctx); } }
void client_activity_cb(struct ev_loop *loop, ev_io *w, int revents) { struct tls_user_context_t *context = (struct tls_user_context_t *) w->data; /* get_client_datas_by_socket acquire client datas lock if session is found */ user_session_t *c_session = get_client_datas_by_socket(w->fd); if (! c_session) { log_message(WARNING, DEBUG_AREA_USER, "Unable to find session for %d", w->fd); return; } debug_log_message(VERBOSE_DEBUG, DEBUG_AREA_USER, "User activity for \"%s\" (in cb)", c_session->user_name); if (c_session->activated) { c_session->activated = FALSE; } ev_io_stop(context->loop, w); if (revents & EV_ERROR) { log_message(INFO, DEBUG_AREA_USER, "Error on socket %d", w->fd); delete_locked_client_by_socket(w->fd); unlock_client_datas(); return; } if (revents & EV_READ) { debug_log_message(VERBOSE_DEBUG, DEBUG_AREA_USER, "Reading needed for user \"%s\"(in cb)", c_session->user_name); g_async_queue_push(c_session->workunits_queue, GINT_TO_POINTER(0x1)); thread_pool_push(nuauthdatas->user_workers, c_session, NULL); unlock_client_datas(); return; } /* we should not reach this point */ log_message(WARNING, DEBUG_AREA_USER, "Surprising event from libev: %d", revents); /* disconnecting session to be sure */ if (g_mutex_trylock(c_session->rw_lock)) { delete_rw_locked_client(c_session); } else { c_session->pending_disconnect = TRUE; } unlock_client_datas(); }
/** * \brief Entry point of the program. * \param argc number of arguments. * \param argv array of arguments. * \return EXIT_SUCCESS or EXIT_FAILURE. */ int main(int argc, char** argv) { const size_t tasks_size = 20; thread_pool th = NULL; struct thread_pool_task tasks[tasks_size]; (void)argc; (void)argv; fprintf(stdout, "Begin\n"); th = thread_pool_new(10); fprintf(stdout, "Thread pool: %p\n", (void*)th); if(!th) { fprintf(stderr, "Failed to create pool errno=%d\n", errno); exit(EXIT_FAILURE); } for(unsigned int i = 0 ; i < tasks_size ; i++) { tasks[i].data = (void*)(uintptr_t)i; tasks[i].run = fcn_run; tasks[i].cleanup = fcn_cleanup; if(thread_pool_push(th, &tasks[i]) != 0) { fprintf(stderr, "Failed to add task %u\n", i); } } thread_pool_start(th); sleep(1); fprintf(stdout, "Stop stuff\n"); thread_pool_stop(th); fprintf(stdout, "Free stuff\n"); thread_pool_free(&th); fprintf(stdout, "OK\n"); fprintf(stdout, "End\n"); return EXIT_SUCCESS; }
bool thread_pool_barrier_wait (struct thread_pool *pool) { size_t max_threads = pool->num_threads; loomlib_barrier_t* barrier; pthread_mutex_lock (&pool->lock); loomlib_barrier_init (barrier, NULL, pool->num_threads + 1); while (max_threads--) thread_pool_push (pool, barrier_thread, &barrier); loomlib_barrier_wait (barrier); loomlib_barrier_destroy (barrier); pthread_mutex_unlock (&pool->lock); return true; }
int main(int argc, char* argv[]) { char c; int cpu = system_getcpucount(); socket_t server; aio_socket_t aioserver; memset(s_buffer, 'A', sizeof(s_buffer)-1); aio_socket_init(cpu); s_thpool = thread_pool_create(cpu, cpu, cpu*2); while(cpu > 0) { thread_pool_push(s_thpool, AIOWorker, NULL); --cpu; } server = Listen(50000); aioserver = aio_socket_create(server, 1); aio_socket_accept(aioserver, OnAccept, aioserver); printf("server listen at: %d\n", 50000); for(c = getchar(); 'q' != c; c = getchar()) { switch(c) { case 'c': // close socket aio_socket_destroy(aioserver); break; default: printf("unknown command.\nc : close socket\n"); } } aio_socket_destroy(aioserver); thread_pool_destroy(s_thpool); aio_socket_clean(); return 0; }
int main(int argc, char* argv[]) { #if defined(OS_LINUX) /* ignore pipe signal */ struct sigaction sa; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, 0); sigaction(SIGPIPE, &sa, 0); #endif int port = 554; for(int i=1; i<argc; i++) { if(streq(argv[i], "--port") && i+1<argc) { port = atoi(argv[++i]); } } size_t cpu = system_getcpucount(); g_thpool = thread_pool_create(cpu, cpu, cpu*4); aio_socket_init(cpu * 2); for(size_t i=0; i<cpu * 2; i++) thread_pool_push(g_thpool, AioWorker, NULL); // start worker // start server StartTcpServer(NULL, port); StartUdpServer(NULL, port); for(int c = getchar(); 'q' != c ; c = getchar()) { } aio_socket_destroy(s_tcp); aio_socket_clean(); thread_pool_destroy(g_thpool); return 0; }
FixedPostingList * fixed_index_multithreaded_multiphrase_get (const FixedIndex *findex, ThreadPool *pool, GList *phrases) { FixedPostingList *base_list, *succ_list, *tmp_list; tp_arg_t *arg; GList *phrase_cell; guint idx; g_return_val_if_fail(findex, NULL); g_return_val_if_fail(pool, NULL); g_return_val_if_fail(phrases, NULL); for(phrase_cell = phrases; phrase_cell != NULL; phrase_cell = phrase_cell->next) { arg = g_malloc(sizeof(tp_arg_t)); arg->findex = findex; arg->phrase = phrase_cell->data; arg->list = NULL; thread_pool_push(pool, arg); } arg = thread_pool_pop(pool); base_list = arg->list; g_free(arg); for (idx = 1; idx < g_list_length(phrases); idx++) { arg = thread_pool_pop(pool); succ_list = arg->list; tmp_list = fixed_posting_list_doc_intersect(base_list, succ_list); fixed_posting_list_free(base_list); fixed_posting_list_free(succ_list); g_free(arg); base_list = tmp_list; } return base_list; }
int sys_thread_pool_push(sys_thread_pool_proc proc, void *param) { return thread_pool_push(g_pool, proc, param); }
bool thread_pool_terminate (struct thread_pool *pool) { return thread_pool_push (pool, THREAD_POOL_TERM_SIG, NULL); }
/** * Function called on new client connection: * - Call accept() * - Drop client if there are to much clients or if NuAuth is in reload * - Create a client_connection structure * - Add client to ::pre_client_list * - Add client to ::tls_sasl_worker queue (see sasl_worker()) * * \return If an error occurs returns 1, else returns 0. */ int tls_user_accept(struct tls_user_context_t *context) { struct sockaddr_storage sockaddr; struct sockaddr_in *sockaddr4 = (struct sockaddr_in *) &sockaddr; struct sockaddr_in6 *sockaddr6 = (struct sockaddr_in6 *) &sockaddr; struct in6_addr addr; unsigned int len_inet = sizeof sockaddr; struct client_connection *current_client_conn; struct pre_client_elt *new_pre_client; int socket; gint option_value; unsigned short sport; char address[INET6_ADDRSTRLEN]; current_client_conn = g_new0(struct client_connection, 1); current_client_conn->nussl = nussl_session_accept(context->nussl); if ( ! current_client_conn->nussl ) { /* can be triggered by EAGAIN on non blocking accept socket */ g_free(current_client_conn); return 1; } if (nussl_session_getpeer(current_client_conn->nussl, (struct sockaddr *) &sockaddr, &len_inet) != NUSSL_OK) { log_message(WARNING, DEBUG_AREA_MAIN | DEBUG_AREA_USER, "New client connection failed during nussl_session_getpeer(): %s", nussl_get_error(context->nussl)); g_free(current_client_conn); return 1; } socket = nussl_session_get_fd(current_client_conn->nussl); /* if system is in reload: drop new client */ if (nuauthdatas->need_reload) { shutdown(socket, SHUT_RDWR); close(socket); return 0; } /* Extract client address (convert it to IPv6 if it's IPv4) */ /* if (sockaddr.ss_family == AF_INET) { -> same as tls_nufw.c */ if (sockaddr6->sin6_family == AF_INET) { ipv4_to_ipv6(sockaddr4->sin_addr, &addr); sport = ntohs(sockaddr4->sin_port); } else { addr = sockaddr6->sin6_addr; sport = ntohs(sockaddr6->sin6_port); } format_ipv6(&addr, address, sizeof(address), NULL); log_message(DEBUG, DEBUG_AREA_MAIN | DEBUG_AREA_USER, "nuauth: user connection attempt from %s\n", address); if (get_number_of_clients() >= context->nuauth_tls_max_clients) { log_message(WARNING, DEBUG_AREA_MAIN | DEBUG_AREA_USER, "too many clients (%d configured)", context->nuauth_tls_max_clients); shutdown(socket, SHUT_RDWR); close(socket); return 1; } current_client_conn->socket = socket; current_client_conn->addr = addr; current_client_conn->sport = sport; current_client_conn->str_addr = g_strdup(address); current_client_conn->srv_context = context; /* Set KEEP ALIVE on connection */ option_value = 1; setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &option_value, sizeof(option_value)); /* give the connection to a separate thread */ /* add element to pre_client create pre_client_elt */ new_pre_client = g_new0(struct pre_client_elt, 1); new_pre_client->socket = socket; new_pre_client->validity = time(NULL) + context->nuauth_auth_nego_timeout; g_static_mutex_lock(&pre_client_list_mutex); pre_client_list = g_slist_prepend(pre_client_list, new_pre_client); g_static_mutex_unlock(&pre_client_list_mutex); thread_pool_push(nuauthdatas->tls_sasl_worker, current_client_conn, NULL); return 0; }
/** * Thread which process addresses on tls push queue (tls_push_queue member * of ::nuauthdatas) which need an authentication. * * Lock is only needed when modifications are done, because when this thread * work (push mode) it's the only one who can modify the hash. * * Use a switch: * - #WARN_MESSAGE: call warn_clients() (and may call ip_authentication_workers()) * - #INSERT_MESSAGE: call add_client() */ void *push_worker(GMutex * mutex) { struct msg_addr_set *global_msg = g_new0(struct msg_addr_set, 1); struct nu_srv_message *msg = g_new0(struct nu_srv_message, 1); struct internal_message *message; GTimeVal tv; msg->type = SRV_REQUIRED_PACKET; msg->option = 0; msg->length = htons(4); global_msg->msg = msg; g_async_queue_ref(nuauthdatas->tls_push_queue); /* wait for message */ while (g_mutex_trylock(mutex)) { g_mutex_unlock(mutex); /* wait a message during POP_DELAY */ g_get_current_time(&tv); g_time_val_add(&tv, POP_DELAY); message = g_async_queue_timed_pop(nuauthdatas->tls_push_queue, &tv); if (message == NULL) continue; switch (message->type) { case WARN_MESSAGE: global_msg->addr = (((auth_pckt_t *) message->datas)->header).saddr; global_msg->found = FALSE; /* search in client array */ warn_clients(global_msg, NULL, NULL); /* do we have found something */ if (!ipv6_equal(&global_msg->addr, &in6addr_any)) { if (global_msg->found == FALSE) { /* if we do ip authentication send request to pool */ if (nuauthconf-> do_ip_authentication) { thread_pool_push (nuauthdatas-> ip_authentication_workers, message->datas, NULL); } else { g_free(message->datas); } } else { /* free header */ g_free(message->datas); } } break; case INSERT_MESSAGE: { struct tls_insert_data *data = message->datas; if (data->data) { add_client(data->socket, data->data); } g_free(data); } break; default: g_message("lost"); } g_free(message); } g_free(msg); g_free(global_msg); g_async_queue_unref(nuauthdatas->tls_push_queue); return NULL; }
int gurls( FILE* fin, uint32_t threads ) { struct thread_pool *pool; uint32_t i; char url[1024]; char saftey_ext[5] = "txt\0"; /* validate threads */ threads = threads > 30 ? 30 : threads == 0 ? 5 : threads; pool = thread_pool_new( threads ); if( !pool ) { return -1; } /* initialize curl */ curl_global_init( CURL_GLOBAL_ALL ); for( i = 0; fgets(url, 1024, fin) ; i++ ) { gurl_url_t* u; char* aux; if( *url == '\n' || *url == '\0' ) { break; } if( !is_url(url) ) { i--; continue; } /* create url object */ u = malloc( sizeof(gurl_url_t) ); if( !u ) { break; } /* remove trailing newline */ for( aux = url; aux-url < 1024 && *aux != '\n' && *aux != '\0'; aux++ ); *aux = '\0'; /* fill up url object */ strncpy( u->url, url, 1024 ); aux = get_extension( url ); if( !aux ) aux = saftey_ext; snprintf( u->filename, 1024, "file-%010d.%s", i, aux ); thread_pool_push( pool, gurl_url_download, u ); } /* send term signal to children */ thread_pool_terminate( pool ); /* cleanup */ thread_pool_free( pool ); curl_global_cleanup(); return 0; }