/** perform extended threaded test */ static int ext_test(struct ub_ctx* ctx, int argc, char** argv) { struct ext_thr_info inf[NUMTHR]; int i; if(argc == 1 && strcmp(argv[0], "localhost") == 0) q_is_localhost = 1; printf("extended test start (%d threads)\n", NUMTHR); for(i=0; i<NUMTHR; i++) { /* 0 = this, 1 = library bg worker */ inf[i].thread_num = i+2; inf[i].ctx = ctx; inf[i].argc = argc; inf[i].argv = argv; inf[i].numq = 100; ub_thread_create(&inf[i].tid, ext_thread, &inf[i]); } /* the work happens here */ for(i=0; i<NUMTHR; i++) { ub_thread_join(inf[i].tid); } printf("extended test end\n"); ub_ctx_delete(ctx); checklock_stop(); return 0; }
void wsvc_cron_cb(void* arg) { /* perform cronned operation */ verbose(VERB_ALGO, "cron timer callback"); if(cron_thread == NULL) { /* create new thread to do it */ ub_thread_create(&cron_thread, win_do_cron, arg); } /* reschedule */ set_cron_timer(); }
/** * Fork and init the other threads. Main thread returns for special handling. * @param daemon: the daemon with other threads to fork. */ static void daemon_start_others(struct daemon* daemon) { int i; log_assert(daemon); verbose(VERB_ALGO, "start threads"); /* skip i=0, is this thread */ for(i=1; i<daemon->num; i++) { ub_thread_create(&daemon->workers[i]->thr_id, thread_start, daemon->workers[i]); #ifdef THREADS_DISABLED /* close pipe end of child */ tube_close_read(daemon->workers[i]->cmd); #endif /* no threads */ } }
/** test hash table access by multiple threads */ static void test_threaded_table(struct lruhash* table) { int numth = 10; struct test_thr t[100]; int i; for(i=1; i<numth; i++) { t[i].num = i; t[i].table = table; ub_thread_create(&t[i].id, test_thr_main, &t[i]); } for(i=1; i<numth; i++) { ub_thread_join(t[i].id); } if(0) lruhash_status(table, "hashtest", 1); }
int libworker_bg(struct ub_ctx* ctx) { struct libworker* w; /* fork or threadcreate */ lock_basic_lock(&ctx->cfglock); if(ctx->dothread) { lock_basic_unlock(&ctx->cfglock); w = libworker_setup(ctx, 1, NULL); if(!w) return UB_NOMEM; w->is_bg_thread = 1; #ifdef ENABLE_LOCK_CHECKS w->thread_num = 1; /* for nicer DEBUG checklocks */ #endif ub_thread_create(&ctx->bg_tid, libworker_dobg, w); } else { lock_basic_unlock(&ctx->cfglock); #ifndef HAVE_FORK /* no fork on windows */ return UB_FORKFAIL; #else /* HAVE_FORK */ switch((ctx->bg_pid=fork())) { case 0: w = libworker_setup(ctx, 1, NULL); if(!w) fatal_exit("out of memory"); /* close non-used parts of the pipes */ tube_close_write(ctx->qq_pipe); tube_close_read(ctx->rr_pipe); (void)libworker_dobg(w); exit(0); break; case -1: return UB_FORKFAIL; default: /* close non-used parts, so that the worker * bgprocess gets 'pipe closed' when the * main process exits */ tube_close_read(ctx->qq_pipe); tube_close_write(ctx->rr_pipe); break; } #endif /* HAVE_FORK */ } return UB_NOERROR; }