int main(int argc, char * argv[]) { pthread_t id; struct timespec abstime, reltime = { 1, 0 }; void* result = (void*)-1; assert(pthread_create(&id, NULL, func, (void *)(size_t)999) == 0); /* * Let thread start before we attempt to join it. */ Sleep(100); (void) pthread_win32_getabstime_np(&abstime, &reltime); /* Test for pthread_timedjoin_np timeout */ assert(pthread_timedjoin_np(id, &result, &abstime) == ETIMEDOUT); assert((int)(size_t)result == -1); /* Test for pthread_tryjoin_np behaviour before thread has exited */ assert(pthread_tryjoin_np(id, &result) == EBUSY); assert((int)(size_t)result == -1); Sleep(500); /* Test for pthread_tryjoin_np behaviour after thread has exited */ assert(pthread_tryjoin_np(id, &result) == 0); assert((int)(size_t)result == 999); /* Success. */ return 0; }
static int do_test (void) { pthread_t th; if (pthread_mutex_lock (&lock) != 0) { puts ("mutex_lock failed"); exit (1); } if (pthread_create (&th, NULL, tf, NULL) != 0) { puts ("mutex_create failed"); exit (1); } void *status; int val = pthread_tryjoin_np (th, &status); if (val == 0) { puts ("1st tryjoin succeeded"); exit (1); } else if (val != EBUSY) { puts ("1st tryjoin didn't return EBUSY"); exit (1); } if (pthread_mutex_unlock (&lock) != 0) { puts ("mutex_unlock failed"); exit (1); } while ((val = pthread_tryjoin_np (th, &status)) != 0) { if (val != EBUSY) { printf ("tryjoin returned %s (%d), expected only 0 or EBUSY\n", strerror (val), val); exit (1); } /* Delay minimally. */ struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; nanosleep (&ts, NULL); } if (status != (void *) 42l) { printf ("return value %p, expected %p\n", status, (void *) 42l); exit (1); } return 0; }
int main() { AbsMsg* absmsg; pthread_t tdatarecv, mysqllocal, mysqlcloud, timer; //数据获取、本地数据库存储、云数据库存储、数据库定时器线程 void* threadret; pid_t pid; int status; while(1){ if((pid = fork()) > 0){ //主进程,守护进程 wait(&status); //阻塞,至子进程退出 continue; }else{ //子进程,应用程序 //setsid();//创建新会话 printf(">>>>>>>>>>>>>>>START!>>>>>>>>>>>>>\n"); mysql_library_init(0, NULL, NULL); //mysql 多线程连接初始化 absmsg = (AbsMsg*)malloc(sizeof(AbsMsg)); absmsg->NQueue = (struct NodeNeiQueue*)malloc(sizeof(struct NodeNeiQueue)); absmsg->NQueue->head = 0; absmsg->NQueue->tail = 0; //互斥锁初始化 pthread_mutex_init(&absmsg->ecollock1, NULL); pthread_mutex_init(&absmsg->ecollock2, NULL); //串口数据获取线程 assert(pthread_create(&tdatarecv, NULL, tdatarecv_fn, absmsg) == 0); //本地数据库存储线程 assert(pthread_create(&mysqllocal, NULL, mysqllocal_fn, absmsg) == 0); //云端数据库存储线程,允许失败 pthread_create(&mysqlcloud, NULL, mysqlcloud_fn, absmsg); //定时器线程 assert(pthread_create(&timer, NULL, timer_fn, NULL) == 0); while(1){ //监控四个线程,有退出则重启 if(pthread_tryjoin_np(tdatarecv,NULL) == 0) assert(pthread_create(&tdatarecv, NULL, tdatarecv_fn, absmsg) == 0); if(pthread_tryjoin_np(mysqllocal,NULL) == 0) assert(pthread_create(&mysqllocal, NULL, mysqllocal_fn, absmsg) == 0); if(pthread_tryjoin_np(mysqlcloud,NULL) == 0) pthread_create(&mysqlcloud, NULL, mysqlcloud_fn, absmsg); if(pthread_tryjoin_np(timer,NULL) == 0) assert(pthread_create(&timer, NULL, timer_fn, NULL) == 0); sleep(1); } } } }
int pthread_join(pthread_t tid, void** value_ptr) { int rc; static int (*real_join)(pthread_t,void *) = NULL; if (!real_join) real_join = dlsym(RTLD_NEXT, "pthread_join"); if(!no_follow() && !RECORD_MODE) { int id = get_instrumented_id(tid); if(VERBOSE) { fprintf(stderr, "Waiting for thread %d to join!\n", id); } step_and_notify(); wait(); int res = pthread_tryjoin_np(tid,value_ptr); if(res != EBUSY) { return res; } if(no_follow()) { return real_join(tid, value_ptr); } step_and_notify(); wait(); res = pthread_tryjoin_np(tid,value_ptr); if(res != EBUSY) { return res; } if(no_follow()) { pthread_cond_broadcast(&step_condition); return real_join(tid, value_ptr); } step_and_notify(); wait(); res = pthread_tryjoin_np(tid, value_ptr); if(res != EBUSY) { return res; } return pthread_tryjoin_np(tid, value_ptr); } else { step_and_notify(); rc = real_join(tid, value_ptr); return rc; } }
int main(void) { Event *e; int fd, wd; struct data_t data; for (e = event_types; e->description; ++e) { fprintf(stderr, "[INFO] code %d: %s\n", e->inotify_code, e->description); } if ((fd = inotify_init()) < 0) { /* FIXME init failed */ } if ((wd = inotify_add_watch(fd, ".", IN_CREATE)) < 0) { /* FIXME add watch failed */ } if (pthread_create(&data.tid, NULL, &handle, &data)) { /* FIXME pthread create failed */ } while (pthread_tryjoin_np(data.tid, NULL)) { /* TODO stuff */ } if (inotify_rm_watch(fd, wd)) { /* FIXME remove watch failed */ } if (close(fd)) { /* FIXME close failed */ } return EXIT_SUCCESS; }
void term_agents() /* * Terminate all of the agents. * Send each one the termination signal and also make a list of * all of the threads. When all of the signals have been sent * then we wait for all of the threads to die. */ { GSList *agent_threads = NULL; /* List of agent threads */ GSList *node; /* Single node in the list */ int stat; /* Status */ for_each_obj(qsheets, (t_for_obj)send_qsheet_term, &agent_threads); if(agent4mxrs) { agent_threads = g_slist_prepend(agent_threads, (void *)agent4mxrs->thread); client2agent_tx(client4mxrs, am_terminate, NULL); } if(agent4deks) { agent_threads = g_slist_prepend(agent_threads, (void *)agent4deks->thread); client2agent_tx(client4deks, am_terminate, NULL); } /* * Reverse the list so that we traverse it in the same order the * termination signals were sent - should be slightly quicker */ agent_threads = g_slist_reverse(agent_threads); D(5, "Waiting for agents to die ...."); for(node = agent_threads; node; node = node->next) { if(!node->data) /* No agent? */ continue; do { while(gtk_events_pending())/* Any GUI events? */ gtk_main_iteration();/* Process them */ stat = pthread_tryjoin_np((pthread_t)node->data, NULL); if(stat) /* Unsuccessful */ msleep(10); /* Sleep for 10 ms */ } while (stat != 0); /* Hasn't died yet */ } D(5, "Done - all agent threads closed"); g_slist_free(agent_threads); del_am_pool(); } /* term_agents() */
TEST(configure_tty, with_socat) { int socat_pid; int serial_fd; unsigned char rx_buff[2048]; pthread_t thread; socat_pid = start_socat(); serial_fd = configure_tty(tty_path); pthread_create(&thread, NULL, write_data_thread, &serial_fd); // read all packets while (received_packets < number_packets) { int n_chars = receive_data(serial_fd, rx_buff, 2048, handle_pkt); if (n_chars == -1) { // Happend when 'socat' didn't run correctly // Break to prevent infinite loop // // Main code does also quits when ret <= 0 fprintf(stderr, "ABORTING: %s\n", strerror(errno)); break; } } /* wait for writer thread */ while (pthread_tryjoin_np(thread, NULL)) sleep(1); ASSERT_EQ(number_packets, received_packets); kill(socat_pid, SIGINT); }
int CMmcThreadPosix::IsRunning() { int rc = ENOENT; if( m_thread != 0 ) rc = pthread_tryjoin_np(m_thread, NULL); return ( rc == EBUSY ); }
bool UDTPPeer::add_thread() { if(!is_online()) return false; /*Not online? Can't add!*/ unsigned int flowSocket; flowSocket = socket(AF_INET, SOCK_DGRAM, 0); if(flowSocket <0) return false; int optval = 1; if((setsockopt(flowSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) < 0) return false; struct sockaddr_in flowAddress; if(host_local()){ /*HOSTs have several destinations but luckily we stored the address on connect() here!*/ /*Only downside is that when we receive messages from PEER on UDPs that we will not know where it is coming from!*/ flowAddress = get_address(); }else{ /*PEER's only have one destination and that is the HOST!*/ flowAddress.sin_addr.s_addr = inet_addr(udtp()->setup()->get_ip()); flowAddress.sin_port = htons(udtp()->setup()->get_port()); flowAddress.sin_family = AF_INET; } if( (bind(flowSocket, (struct sockaddr*)&flowAddress, sizeof(flowAddress))) < 0 ) { perror("udp-bind"); return false; } /*Start a flow thread!*/ pthread_t flowThreadHandler; UDTPThreadFlow *newFlowThread = new UDTPThreadFlow((UDTP*)this, flowThreadHandler, flowSocket); newFlowThread->set_peer(this); pthread_create(&flowThreadHandler, NULL, UDTPPeer::flowThread, (UDTPThreadFlow*)newFlowThread); pthread_tryjoin_np(flowThreadHandler, NULL); /*Start a process thread!*/ pthread_t processThreadHandler; UDTPThreadProcess *newProcessThread = new UDTPThreadProcess(); newProcessThread->set_peer(this); pthread_create(&processThreadHandler, NULL, UDTPPeer::flowThread, (UDTPThreadProcess*)newProcessThread); pthread_tryjoin_np(processThreadHandler, NULL); std::cout << "PEER " << get_unique_id() << " has added a flow and process thread!" << std::endl; increment_thread_count(); return true; }
int main(int argc, char * argv[]) { pthread_t id; struct timespec abstime; void* result = (void*)-1; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_create(&id, NULL, func, (void *)(size_t)999) == 0); /* * Let thread start before we attempt to join it. */ Sleep(100); PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; /* Test for pthread_timedjoin_np timeout */ abstime.tv_sec += 1; assert(pthread_timedjoin_np(id, &result, &abstime) == ETIMEDOUT); assert((int)(size_t)result == -1); /* Test for pthread_tryjoin_np behaviour before thread has exited */ assert(pthread_tryjoin_np(id, &result) == EBUSY); assert((int)(size_t)result == -1); Sleep(500); /* Test for pthread_tryjoin_np behaviour after thread has exited */ assert(pthread_tryjoin_np(id, &result) == 0); assert((int)(size_t)result == 999); /* Success. */ return 0; }
int OSAL_tryjoin_thread(OSAL_thread_t thread_id, void **status) { #ifndef WIMAX_SYS_WINDOWS int ret = pthread_tryjoin_np((pthread_t)thread_id, status); if ( ret != 0 ) OSALTRACE(OSAL_ERROR, ("thread try join failed. err: %d", errno)); return ret; #else #endif }
int pthread_join(pthread_t tid, void** value_ptr) { step_and_notify(); wait(); int res = pthread_tryjoin_np(tid,value_ptr); if(res != EBUSY) { return res; } step_and_notify(); wait(); res = pthread_tryjoin_np(tid,value_ptr); if(res != EBUSY) { return res; } assert(false && "Invalid Schedule!"); }
int main(int argc, char *argv[]) { int err; void *res; struct tt_thread_info ti = { 0, .thread_name = "tt-test", .thread_prio = 0 }; if (argc == 2) { ti.dev = argv[1]; } else { ti.dev = NULL; } /* start & run thread for capture and interval processing */ err = tt_intervals_init(&ti); if (err) { handle_error_en(err, "tt intervals init"); } err = pthread_attr_init(&ti.attr); if (err) { handle_error_en(err, "pthread_attr_init"); } err = pthread_create(&ti.thread_id, &ti.attr, tt_intervals_run, &ti); if (err) { handle_error_en(err, "pthread_create"); } tt_update_ref_window_size(&ti, tt_intervals[0]); tt_update_ref_window_size(&ti, tt_intervals[INTERVAL_COUNT - 1]); /* check if the thread is still alive */ if (EBUSY != pthread_tryjoin_np(ti.thread_id, &res)) { handle_error_en(err, "pthread_tryjoin_np"); } pthread_cancel(ti.thread_id); pthread_join(ti.thread_id, &res); tt_intervals_free(&ti); return 0; }
void lwan_thread_shutdown(lwan_t *l) { lwan_status_debug("Shutting down threads"); for (int i = l->thread.count - 1; i >= 0; i--) { lwan_thread_t *t = &l->thread.threads[i]; /* Closing epoll_fd makes the thread gracefully finish. */ close(t->epoll_fd); close(t->pipe_fd[0]); close(t->pipe_fd[1]); pthread_tryjoin_np(l->thread.threads[i].self, NULL); } free(l->thread.threads); }
int gpio_set_int (unsigned int pin, void (*isr) (int), char *mode) { /* Details of the ISR */ isr_t *i = (isr_t *) malloc(sizeof (isr_t)); i->pin = pin; i->isr = isr; /* Set up interrupt */ gpio_edge(pin, mode); /* Set isr_handler flag and create thread TODO: check for errors using retval */ isr_handler_flag = 1; pthread_create(&isr_handler_thread, NULL, isr_handler, (void *) i); pthread_tryjoin_np(isr_handler_thread, NULL); return 1; }
/////////////////////////////////////////////////////////////////////// /// Function: TryJoin /// /// Author: $author$ /// Date: 4/13/2012 /////////////////////////////////////////////////////////////////////// virtual XosError TryJoin(void*& result) { XosError error = XOS_ERROR_FAILED; int err; if ((m_isCreated)) { if (!(err = pthread_tryjoin_np(m_thread, &result))) error = XOS_ERROR_NONE; else if (EBUSY == (err)) { XOS_DBT(("() busy on pthread_tryjoin_np()")); error = XOS_ERROR_BUSY; } else { XOS_DBE(("() failed on pthread_tryjoin_np()")); } if (EBUSY != (err)) m_isForked = false; } return error; }
static void http_engine_check_activity(int fd, short kind, void *userp) { int i, error = 0; if (!g_http_engine->workers_running) { if (evtimer_pending(g_http_engine->activity_timer_event, NULL)) { evtimer_del(g_http_engine->activity_timer_event); } return; } for (i = 0; i < g_http_engine->total_workers; i++) { if (g_http_engine->workers[i].worker) { error |= pthread_tryjoin_np(g_http_engine->workers[i].worker, NULL); } } if (!error) { /* Workers are done */ pthread_mutex_lock(&g_http_engine->lock); g_http_engine->workers_running = 0; pthread_mutex_unlock(&g_http_engine->lock); if (evtimer_pending(g_http_engine->activity_timer_event, NULL)) { evtimer_del(g_http_engine->activity_timer_event); } zlog_info(log_get_cat_http(), "Http workers terminated normally"); http_process_test_completed(); return; } http_engine_activity_timer_update(); }
int FfmpegCamera::Capture( Image &image ) { if (!mCanCapture){ return -1; } // If the reopen thread has a value, but mCanCapture != 0, then we have just reopened the connection to the ffmpeg device, and we can clean up the thread. if (mReopenThread != 0) { void *retval = 0; int ret; ret = pthread_tryjoin_np(mReopenThread, &retval); if (ret != 0){ Error("Could not join reopen thread."); } Info( "Successfully reopened stream." ); mReopenThread = 0; } AVPacket packet; uint8_t* directbuffer; /* Request a writeable buffer of the target image */ directbuffer = image.WriteBuffer(width, height, colours, subpixelorder); if(directbuffer == NULL) { Error("Failed requesting writeable buffer for the captured image."); return (-1); } int frameComplete = false; while ( !frameComplete ) { int avResult = av_read_frame( mFormatContext, &packet ); if ( avResult < 0 ) { char errbuf[AV_ERROR_MAX_STRING_SIZE]; av_strerror(avResult, errbuf, AV_ERROR_MAX_STRING_SIZE); if ( // Check if EOF. (avResult == AVERROR_EOF || (mFormatContext->pb && mFormatContext->pb->eof_reached)) || // Check for Connection failure. (avResult == -110) ) { Info( "av_read_frame returned \"%s\". Reopening stream.", errbuf); ReopenFfmpeg(); } Error( "Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, avResult, errbuf ); return( -1 ); } Debug( 5, "Got packet from stream %d", packet.stream_index ); if ( packet.stream_index == mVideoStreamId ) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 25, 0) if ( avcodec_decode_video2( mCodecContext, mRawFrame, &frameComplete, &packet ) < 0 ) #else if ( avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size ) < 0 ) #endif Fatal( "Unable to decode frame at frame %d", frameCount ); Debug( 4, "Decoded video packet at frame %d", frameCount ); if ( frameComplete ) { Debug( 3, "Got frame %d", frameCount ); avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); #if HAVE_LIBSWSCALE if(mConvertContext == NULL) { if(config.cpu_extensions && sseversion >= 20) { mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC | SWS_CPU_CAPS_SSE2, NULL, NULL, NULL ); } else { mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL ); } if(mConvertContext == NULL) Fatal( "Unable to create conversion context for %s", mPath.c_str() ); } if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 ) Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount ); #else // HAVE_LIBSWSCALE Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" ); #endif // HAVE_LIBSWSCALE frameCount++; } } av_free_packet( &packet ); } return (0); }
uint8_t thread_running(pthread_t t){ int r = pthread_tryjoin_np(t, NULL); return (r==0 || r==EBUSY); }
//-----main function------------------------------------------------------------------------------------------------------------ int main( int argc, char *argv[] ) { if (argc == 2) //shortcut to daemonize or not { if (strcmp(argv[1],"1") == 0) {daemonize();} } struct clientParams controlClient[MAXTHREADS]; //array of struct which control the threads pthread_t clientThreads[MAXTHREADS]; //array of threads int clientSocket[MAXTHREADS]; int yes = 1; //used in setsockopt function int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information socklen_t sin_size; int i=0; FILE *fUser; //the users present in the file are copied to the array if(fUser=fopen("user.txt","r")) { while(fscanf(fUser,"%s %s",userInfo[numUsers].user, userInfo[numUsers].pass)==2) { numUsers++;} fclose(fUser); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(sockfd,SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int)) == -1) { perror("setsockopt"); exit(1); } my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero); if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) { perror("bind"); exit(1); } if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } int reset = 0; //checks if all the threads are used struct timeval timeout; //used for creating the timeout timeout.tv_usec = 0; //needed as parameter, else timeout doesnt work since it takes any random value char recvCheck[DATASIZE]; //recieve the message during timeout, control for setsockopt for(;;) { printf("id: %d Waiting for a connection...\n", getpid()); //since we use 2 threads for each client, other connections with 1 socket are denied if ((clientSocket[i] = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept");} //1st connection timeout.tv_sec = 1; //timeout is set to 1 sec if(setsockopt(clientSocket[i], SOL_SOCKET, SO_RCVTIMEO, (struct timeout *)&timeout, sizeof(timeout)) < 0) {perror("setsockopt failed");} recv(clientSocket[i], recvCheck, DATASIZE, 0); //recv is active for 1 sec timeout.tv_sec = 0; //timeout is disabled if(setsockopt(clientSocket[i], SOL_SOCKET, SO_RCVTIMEO, (struct timeout *)&timeout, sizeof(timeout)) < 0) {perror("setsockopt failed");} if (strcmp(recvCheck, "thing") == 0) //if the right string was recieved during 1 sec, accept the connection from next socket, run the program { printf("I got the right thing.\n"); if ((clientSocket[i+1] = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept");} printf("Accepted Connections\n"); if (reset) //if reset=1, join present i and i+1 threads before creating new threads { pthread_tryjoin_np(clientThreads[i], NULL); pthread_tryjoin_np(clientThreads[i+1], NULL); } printf("Creating thread %d\n", i); //Thread 1: listener function controlClient[i].threadId=i; controlClient[i].clientSocket=clientSocket[i]; controlClient[i].recvError = 0; pthread_create(&clientThreads[i], NULL, &serverListener, &controlClient[i]); printf("Creating thread %d\n", i+1); //Thread 2: sender function controlClient[i+1].threadId=(i+1); controlClient[i+1].clientSocket=clientSocket[i+1]; controlClient[i+1].recvError = 0; pthread_create(&clientThreads[i+1], NULL, &serverSender, &controlClient[i+1]); i+=2; //increased by 2 since threads work in pairs if (i == MAXTHREADS) //if all threads are used, start over from 0 { i = 0; reset = 1; } strcpy(recvCheck, " "); //reset the recvCheck to check further incoming connections } else //if nothing or something wrong with one socket was recieved, close the current socket and restart the loop { printf("I didnt get the right thing. Closing socket.\n"); close(clientSocket[i]); } } return 0; }
// wait for the S3 GET/PUT to complete int stream_sync(ObjectStream* os) { /// // TBD: this should be a per-repo config-option /// static const time_t timeout_sec = 5; void* retval; // fuse may call fuse-flush multiple times (one for every open stream). // but will not call flush after calling close(). if (! (os->flags & OSF_OPEN)) { LOG(LOG_ERR, "%s isn't open\n", os->url); errno = EINVAL; /* ?? */ return -1; } // See NOTE, above, regarding the difference between reads and writes. if (! pthread_tryjoin_np(os->op, &retval)) { LOG(LOG_INFO, "op-thread joined\n"); os->flags |= OSF_JOINED; } else { // If a stream_get/put timed-out waiting for their // writefunc/readfunc, then the locks are likely in an inconsistent // state. [Either (a) the readfunc never posted iob_empty for // stream__put(), or (b) the writefunc never posted iob_full for // stream_get().] In either case, the operation started by // stream_open() is declared a failure, and we shouldn't do any of // the normal cleanup stuff, like trying to write recovery-info, etc. // But we do need to the thread to stop before we return, because if // the writefunc/readfunc gets another callback, it will access parts // of the ObjectStream that are about to be deallocated. if (os->flags & OSF_TIMEOUT) { LOG(LOG_INFO, "cancelling timed-out thread\n"); int rc = pthread_cancel(os->op); if (rc) { LOG(LOG_ERR, "cancellation failed (%s), killing thread\n", strerror(errno)); pthread_kill(os->op, SIGKILL); LOG(LOG_INFO, "killed thread\n"); } LOG(LOG_INFO, "waiting for terminated op-thread\n"); if (stream_wait(os)) { LOG(LOG_ERR, "err joining op-thread ('%s')\n", strerror(errno)); return -1; } } // In this case, the get/put timed-out, but it did so inside SAFE_WAIT_KILL(), // rather than SAFE_WAIT(), so the thread has already been cancelled // and joined. else if (os->flags & OSF_TIMEOUT_K) { LOG(LOG_INFO, "timed-out thread already killed\n"); LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc); errno = (os->op_rc ? EIO : 0); return os->op_rc; } #if (LIBCURL_VERSION_MAJOR > 7) || ((LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR >= 45)) // Our installed version of libcurl is 7.19.7. We are experimenting // with a custom-built libcurl based on 7.45.0. We notice that the // latter does not call streaming_readfunc() again, if stream_open() // provided a content-length (i.e. the request had a content-length // header, rather than being chunked-transfer-encoded), and the full // number of chars matching the content-length header has been sent. // In such a case, stream_sync() shouldn't use "stream_put(..0)" to // get the readfunc to quit, because the readfunc isn't running. // // NOTE: This behavior may actually be present in earlier versions of // libcurl, in which case, the VERSION_MINOR here should be // adjusted downwards, toward 19. else if ((os->flags & OSF_WRITING) && os->content_len && (os->content_len == os->written)) { LOG(LOG_INFO, "(wr) wrote content-len, no action needed (flags=0x%04x)\n", os->flags); } #endif // signal EOF to readfunc else if (os->flags & OSF_WRITING) { LOG(LOG_INFO, "(wr) sending empty buffer (flags=0x%04x)\n", os->flags); if (stream_put(os, NULL, 0)) { LOG(LOG_ERR, "stream_put(0) failed\n"); pthread_kill(os->op, SIGKILL); LOG(LOG_INFO, "killed thread\n"); } } // signal QUIT to writefunc else { LOG(LOG_INFO, "(rd) sending empty buffer (flags=0x%04x)\n", os->flags); if (stream_get(os, NULL, 0)) { LOG(LOG_ERR, "stream_get(0) failed\n"); pthread_kill(os->op, SIGKILL); LOG(LOG_INFO, "killed thread\n"); } } // check whether thread has returned. Could mean a curl // error, an S3 protocol error, or server flaking out. LOG(LOG_INFO, "waiting for op-thread\n"); if (stream_wait(os)) { LOG(LOG_ERR, "err joining op-thread ('%s')\n", strerror(errno)); return -1; } } // thread has completed os->flags |= OSF_JOINED; if (( os->flags & OSF_READING) && (os->op_rc == CURLE_WRITE_ERROR)) { // when we signalled writefunc to quit, it provoked this LOG(LOG_INFO, "op-thread returned CURLE_WRITE_ERROR as expected\n"); return 0; } else { LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc); errno = (os->op_rc ? EIO : 0); return os->op_rc; } }
int stream_abort(ObjectStream* os) { /// // TBD: this should be a per-repo config-option /// static const time_t timeout_sec = 5; // fuse may call fuse-flush multiple times (one for every open stream). // but will not call flush after calling close(). if (! (os->flags & OSF_OPEN)) { LOG(LOG_ERR, "%s isn't open\n", os->url); errno = EINVAL; /* ?? */ return -1; } else if (! (os->flags & OSF_WRITING)) { LOG(LOG_ERR, "%s aborting a read-stream is not supported\n", os->url); errno = ENOSYS; return -1; } // See NOTE, above, regarding the difference between reads and writes. void* retval; if (! pthread_tryjoin_np(os->op, &retval)) { LOG(LOG_INFO, "op-thread joined\n"); os->flags |= OSF_JOINED; } else { if (os->flags & OSF_WRITING) { // signal ABORT to readfunc LOG(LOG_INFO, "(wr) sending (char*)1 (flags=0x%04x)\n", os->flags); os->flags |= OSF_ABORT; if (stream_put(os, (const char*)1, 1) != 1) { LOG(LOG_ERR, "stream_put((char*)1) failed\n"); pthread_kill(os->op, SIGKILL); LOG(LOG_INFO, "killed thread\n"); } } // check whether thread has returned. Could mean a curl // error, an S3 protocol error, or server flaking out. LOG(LOG_INFO, "waiting for op-thread\n"); if (stream_wait(os)) { LOG(LOG_ERR, "err joining op-thread\n"); return -1; } } // thread has completed os->flags |= OSF_JOINED; LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc); if ((os->op_rc == CURLE_ABORTED_BY_CALLBACK) && (os->iob.read_pos == (char*)1)) { LOG(LOG_INFO, "op-thread return is as expected for ABORT\n"); return 0; } else { errno = (os->op_rc ? EINVAL : 0); return os->op_rc; } }
/* The main() function/thread creates the worker threads and then waits for * threads to exit or ctrl-c. All code outside the main() function is used by * the worker threads. */ int main(int argc, char *argv[]) { struct worker *workers; char *endptr; size_t sz = DMA_MAP_SIZE; /* Determine number of cores (==number of threads) */ long ncpus = sysconf(_SC_NPROCESSORS_ONLN); /* Load the device-tree driver */ int loop, tmpret, teardown, ret = of_init(); while (ARGINC() > 0) { if (!strcmp(*argv, "-n")) { unsigned long val; if (!ARGINC()) { fprintf(stderr, "Missing argument to -n\n"); exit(EXIT_FAILURE); } val = strtoul(*argv, &endptr, 0); if ((val == ULONG_MAX) || (*endptr != '\0')) { fprintf(stderr, "Invalid argument to -n (%s)\n", *argv); exit(EXIT_FAILURE); } if (!val || (val > ncpus)) { fprintf(stderr, "Out of range (-n %lu)\n", val); exit(EXIT_FAILURE); } ncpus = val; } else if (!strcmp(*argv, "-p")) { if (!ARGINC()) { fprintf(stderr, "Missing argument to -p\n"); exit(EXIT_FAILURE); } PCD_PATH = *argv; } else if (!strcmp(*argv, "-c")) { if (!ARGINC()) { fprintf(stderr, "Missing argument to -c\n"); exit(EXIT_FAILURE); } CFG_PATH = *argv; } else if (!strcmp(*argv, "-s")) { unsigned long val; if (!ARGINC()) { fprintf(stderr, "Missing argument to -s\n"); exit(EXIT_FAILURE); } val = strtoul(*argv, &endptr, 0); if ((val == ULONG_MAX) || (*endptr != '\0') || !val) { fprintf(stderr, "Invalid argument to -s (%s)\n", *argv); exit(EXIT_FAILURE); } sz = (size_t)val; } else if (!strcmp(*argv, "-sc")) { short_circuit_mode = 1; } else if (!strcmp(*argv, "-b")) { unsigned long val; if (!ARGINC()) { fprintf(stderr, "Missing argument to -b\n"); exit(EXIT_FAILURE); } val = strtoul(*argv, &endptr, 0); if ((val == ULONG_MAX) || (*endptr != ':')) goto b_err; bpool_cnt[0] = val; val = strtoul(endptr + 1, &endptr, 0); if ((val == ULONG_MAX) || (*endptr != ':')) goto b_err; bpool_cnt[1] = val; val = strtoul(endptr + 1, &endptr, 0); if ((val == ULONG_MAX) || (*endptr != '\0')) goto b_err; bpool_cnt[2] = val; continue; b_err: fprintf(stderr, "Invalid argument to -b (%s)\n", *argv); exit(EXIT_FAILURE); } else { fprintf(stderr, "Unknown argument '%s'\n", *argv); exit(EXIT_FAILURE); } } printf("Starting hello_reflector, ncpus=%ld\n", ncpus); if (ncpus < 1) { fprintf(stderr, "Fail: # processors: %ld\n", ncpus); exit(EXIT_FAILURE); } if (ret) { fprintf(stderr, "Fail: %s: %d\n", "of_init()", ret); exit(EXIT_FAILURE); } /* Parse FMC policy and configuration files for the network * configuration. This also "extracts" other settings into 'netcfg' that * are not necessarily from the XML files, such as the pool channels * that the application is allowed to use (these are currently * hard-coded into the netcfg code). */ netcfg = usdpaa_netcfg_acquire(PCD_PATH, CFG_PATH); if (!netcfg) { fprintf(stderr, "Fail: usdpaa_netcfg_acquire(%s,%s)\n", PCD_PATH, CFG_PATH); exit(EXIT_FAILURE); } if (!netcfg->num_ethports) { fprintf(stderr, "Fail: no network interfaces available\n"); exit(EXIT_FAILURE); } /* Install ctrl-c handler */ if (signal(SIGINT, handle_sigint) == SIG_ERR) { fprintf(stderr, "Fail: %s\n", "signal(SIGINT)"); exit(EXIT_FAILURE); } /* Allocate the worker structs */ ret = posix_memalign((void **)&workers, MAX_CACHELINE, ncpus * sizeof(*workers)); if (ret) { fprintf(stderr, "Fail: %s: %d\n", "posix_memalign()", ret); exit(EXIT_FAILURE); } /* Load the Qman/Bman drivers */ ret = qman_global_init(); if (ret) { fprintf(stderr, "Fail: %s: %d\n", "qman_global_init()", ret); exit(EXIT_FAILURE); } ret = bman_global_init(); if (ret) { fprintf(stderr, "Fail: %s: %d\n", "bman_global_init()", ret); exit(EXIT_FAILURE); } ret = qman_alloc_pool_range(&pchannels[0], NUM_POOL_CHANNELS, 1, 0); if (ret != NUM_POOL_CHANNELS) { fprintf(stderr, "Fail: no pool channels available\n"); exit(EXIT_FAILURE); } /* Compute SDQCR */ for (loop = 0; loop < NUM_POOL_CHANNELS; loop++) sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(pchannels[loop]); /* Load dma_mem driver */ dma_mem_generic = dma_mem_create(DMA_MAP_FLAG_ALLOC, NULL, sz); if (!dma_mem_generic) { fprintf(stderr, "Fail: %s:\n", "dma_mem_create()"); exit(EXIT_FAILURE); } printf("DMA region created of size %zu (0x%zx)\n", sz, sz); /* Start up the threads */ for (loop = 0; loop < ncpus; loop++) { struct worker *worker = &workers[loop]; worker->quit = worker->init_done = 0; worker->cpu = loop; ret = pthread_create(&worker->id, NULL, worker_fn, worker); if (ret) { fprintf(stderr, "Fail: %s(%d): %d\n", "pthread_create", loop, ret); while (--loop >= 0) { (--worker)->quit = 1; tmpret = pthread_join(worker->id, NULL); if (tmpret) fprintf(stderr, "Fail: %s(%d): %d\n", "pthread_join", loop, tmpret); } exit(EXIT_FAILURE); } /* Wait for thread init to complete (the first thread will * complete global init as part of that) */ while (!worker->init_done) { pthread_yield(); if (!pthread_tryjoin_np(worker->id, NULL)) { fprintf(stderr, "Fail: primary thread init\n"); exit(EXIT_FAILURE); } } } /* Threads are created, now manage them (and catch ctrl-c) */ printf("Hit Ctrl-C (or send SIGINT) to terminate.\n"); teardown = 0; while (ncpus) { if (!teardown) { if (received_sigint) { /* Ctrl-c signal triggers teardown */ teardown = 1; printf("Ctrl-C, ending...\n"); /* Non-primary threads should quit first */ for (loop = 1; loop < ncpus; loop++) workers[loop].quit = 1; } else /* No teardown, no signal, this is where we can * pause */ sleep(1); } else { /* Once the primary thread is the only thread, it can * quit too (global cleanup) */ if (ncpus == 1) workers[0].quit = 1; } /* Reap loop */ loop = 0; while (loop < ncpus) { struct worker *worker = &workers[loop]; if (!pthread_tryjoin_np(worker->id, NULL)) { fprintf(stderr, "Exit: thread %d\n", worker->cpu); if (--ncpus > loop) memmove(worker, worker + 1, (ncpus - loop) * sizeof(*worker)); } else loop++; } } qman_release_pool_range(pchannels[0], NUM_POOL_CHANNELS); printf("Finished hello_reflector\n"); return 0; }
int main(int argc, char **argv) { int x = 0, s = 1, i = 0; char *config_file = "config.cnf", *logfilename = "log.txt", *config_logfilename; int opt = 0; uint32_t end_index= 0; int match_low = -1, match_high = -1; while ((opt = getopt(argc, argv, "s::e::m::b::lhc:")) != -1) { switch (opt) { case 's': //if(TRUE == check_string(optarg)) // start_index = atol(optarg); break; case 'e': if(TRUE == check_string(optarg)) end_index = atol(optarg); break; case 'm': if(TRUE == check_string(optarg)) match_high = atol(optarg); break; case 'b': if(TRUE == check_string(optarg)) match_low = atol(optarg); break; case 'c': if(TRUE == check_string(optarg)) config_file = strdup(optarg); break; case 'l': if(TRUE == check_string(optarg)) logfilename = strdup(optarg); break; case 'h': case '?': fprintf(stderr, "Usage: %s [-c] \"config file\"\n", argv[0]); exit(EXIT_SUCCESS); break; default: break; } } //printf("start index = %u end index = %u optind %i\n",start_index, end_index, optind); main_config = read_config(config_file); if(FAILURE == get_config_string("logfile", main_config, &config_logfilename)) mylogfile = log_open(logfilename); else mylogfile = log_open(config_logfilename); if(match_low >= 0) main_config->match_bail_percentage = match_low; if(match_high >= 0) main_config->match_percentage = match_high; indexdb = open_db(main_config->index_database); ls("Opened index database %s", main_config->index_database); FILE * indexf = fdopen(indexdb->fd, "r"); char buf[65535]; list_container_t ncbi_nt_index; init_list_container(&ncbi_nt_index); uint32_t count = 0; while(NULL != fgets(buf, 65535, indexf) && (0 == end_index || (end_index > 0 && count < end_index))) { add_string_to_list(&ncbi_nt_index, buf); count++; } index_size = ncbi_nt_index.size; ls("Index database line count is %i", index_size); index_offset = malloc(index_size * sizeof(long *)); index_entry = malloc(index_size * sizeof(char *)); index_len = malloc(index_size * sizeof(uint32_t *)); string_list_t *list; db_index_t entry; for(list = ncbi_nt_index.root; list && (0 == end_index || (end_index > 0 && x < (int)end_index)); list = (string_list_t *)list->next, x++) { index_entry[x] = list->str; index_offset[x] = malloc(sizeof(long)); index_len[x] = malloc(sizeof(uint32_t)); entry.str = list->str; *index_offset[x] = get_data_index(&entry); *index_len[x] = entry.datalen; } long nprocessors = sysconf(_SC_NPROCESSORS_ONLN); global_thread_count = 0; pthread_t *threads[nprocessors]; database_t *thread_db[nprocessors]; for(x = 0; x< nprocessors; x++) { threads[x] = NULL; thread_db[x] = NULL; } while(global_thread_count) sleep(1); void *thread_result; int step_size = index_size/1000, launch_thread = FALSE; if(step_size <= 0) step_size+=50; list_container_t main_list; init_list_container(&main_list); list_container_t search_list; data_list_container_t search_list_data; init_list_container(&search_list); init_data_list_container(&search_list_data); for(x = optind;x < argc; x++) { //printf("arguments %i %s\n", x, argv[x]); ls("arguments %i: %s", x, argv[x]); add_string_to_list(&search_list, argv[x]); unsigned int str_len = strlen(argv[x]); uint8_t data[str_len]; uint32_t data_len = 0; compress_dna(data, argv[x], str_len, (int *)&data_len); add_data_to_list(&search_list_data, data, data_len, argv[x], str_len); } //loop through index segments long total = 0; for(i = 0; (unsigned int)i < index_size+step_size; i+=step_size, launch_thread = FALSE) { //loop until thread is launched for this index segment while(FALSE == launch_thread) { //loop through each thread for(x = 0; x< nprocessors; x++) { //check if thread position is running if(NULL != threads[x]) { //check if thread is done and get results s = pthread_tryjoin_np(*threads[x], &thread_result); if(FALSE == s) { list_container_t *temp_list = (list_container_t *) thread_result; string_list_t *last = NULL; if(temp_list->size) for(list = temp_list->root; list && list->str; list = (string_list_t *)list->next) { if(last) { if(last->str) { free(last->str); free(last->score); } free(last); } add_string_to_list(&main_list, list->str); main_list.end->score = memcpy(malloc(sizeof(float)), list->score, sizeof(float)); last = list; } if(last) free(last); free(temp_list); threads[x] = NULL; total += step_size; ls("%li completion = %0.2f\tthread count = %i\tlist size = %li", total, (float)i/(float)index_size, global_thread_count, main_list.size); } } else //launch a new thread { threads[x] = start_thread((void **)&thread_db[x], x, i, i+step_size, (void *)&search_list_data); launch_thread = TRUE; break; } } usleep(10); } } // print final match results for(list = main_list.root; list; list = (string_list_t *)list->next) { ls("%.4f %s", *list->score, list->str); printf("%.4f %s", *list->score, list->str); } close_db(indexdb); return EXIT_SUCCESS; }
void create_thread(void) { int rc; void *receiver_rc = 0, *request_rc[50] = {0}; pthread_t receiver_tid, request_tid[50]; rc = pthread_create(&receiver_tid, NULL, receiver, NULL); if(0 != rc) { log4c_category_log( log_handler, LOG4C_PRIORITY_FATAL, "sync: create receiver thread-- failed"); exit(-5); } log4c_category_log( log_handler, LOG4C_PRIORITY_DEBUG, "sync: create receiver thread -- successful"); int count; for(count = 0; count < server.mysqlThread; count++) { rc = pthread_create(&request_tid[count], NULL, mysql_connector, NULL); if(0 != rc) { log4c_category_log( log_handler, LOG4C_PRIORITY_FATAL, "sync: create mysql_connect thread: %u -- failed", count); exit(-5); } log4c_category_log( log_handler, LOG4C_PRIORITY_DEBUG, "sync: create mysql_connect thread: %u -- successful", count); } while(1) { /*FIXME:moniter thread restat*/ /* *moniter of receiver thread */ /*pthread_join(receiver_tid, &receiver_rc);*/ /*log4c_category_log(*/ /*log_handler, LOG4C_PRIORITY_ERROR,*/ /*"sync: will check thread");*/ pthread_tryjoin_np(receiver_tid, &receiver_rc); if(receiver_rc != 0) { log4c_category_log( log_handler, LOG4C_PRIORITY_ERROR, "sync: receiver thread abnormal termination, %d", receiver_rc); exit(-1); } for(count = 0; count < server.mysqlThread; count++) { pthread_tryjoin_np(request_tid[count], &request_rc[count]); if(request_rc[count] != 0) { log4c_category_log( log_handler, LOG4C_PRIORITY_ERROR, "sync: mysql connector threads\ abnormal termination, %d:%d", count, receiver_rc); exit(-1); } } /*log4c_category_log(*/ /*log_handler, LOG4C_PRIORITY_ERROR,*/ /*"sync: checked thread done");*/ sleep(1); }