static bool fifo_open(struct fifo_data *fd, GError **error) { if (!fifo_check(fd, error)) return false; fd->input = open_cloexec(fd->path, O_RDONLY|O_NONBLOCK, 0); if (fd->input < 0) { g_set_error(error, fifo_output_quark(), errno, "Could not open FIFO \"%s\" for reading: %s", fd->path, strerror(errno)); fifo_close(fd); return false; } fd->output = open_cloexec(fd->path, O_WRONLY|O_NONBLOCK, 0); if (fd->output < 0) { g_set_error(error, fifo_output_quark(), errno, "Could not open FIFO \"%s\" for writing: %s", fd->path, strerror(errno)); fifo_close(fd); return false; } return true; }
void test_empty_thread_pool() { dna_log(INFO, "<-------------------- test_empty_thread_pool ---------------------"); int i = 0; for (i = 0; i < 10 ; i++ ) { dna_log(INFO, ">> --- cycle %i --- <<", i+1); // global here, for all threads to share fifo = fifo_create("values", 0); dna_log(DEBUG, "starting thread pool"); thread_pool_t *pool = thread_pool_create("main pool", 1); dna_log(DEBUG, "destroying thread pool"); thread_pool_exit_all(pool); thread_pool_destroy(pool); fifo_check(); fifo_destroy(fifo); } }
void test_busy_thread_pool() { dna_log(INFO, "<-------------------- test_busy_thread_pool ---------------------"); fifo = fifo_create("<(busy_thread_pool) value fifo>", 0); thread_pool_t *pool = thread_pool_create("<busy thread pool>", 8); // should auto-determine thread count maybe? dna_log(DEBUG, "adding %i tasks to the queue...", ELEMS); int i = 0; for( i = 0; i < ELEMS; i++ ) { thread_pool_enqueue(pool, &fifo_fill, NULL); } dna_log(DEBUG, "waiting for threads to complete on their own..."); thread_pool_exit_all(pool); thread_pool_join_all( pool ); dna_log(DEBUG, "destroying thread pool..."); thread_pool_destroy( pool ); fifo_check(); dna_log(DEBUG, "destroying global value fifo."); fifo_destroy( fifo ); }
/* * Open the FIFO reply file * returns fs no on success, -1 on error */ static int open_reply_pipe(char *pipe_name) { int fifofd; int flags; int retries = fifo_reply_retries; fifofd=-1; if (!pipe_name || *pipe_name == 0) { DBG("No file to write to about missing cmd\n"); goto error; } tryagain: /* open non-blocking to make sure that a broken client will not * block the FIFO server forever */ fifofd = open(pipe_name, O_WRONLY | O_NONBLOCK); if (fifofd == -1) { /* retry several times if client is not yet ready for getting * feedback via a reply pipe */ if (errno == ENXIO) { /* give up on the client - we can't afford server blocking */ if (retries == 0) { ERR("No client at %s\n", pipe_name); goto error; } /* don't be noisy on the very first try */ if (retries != fifo_reply_retries) { DBG("Retry countdown: %d\n", retries); } sleep_us(fifo_reply_wait); retries--; goto tryagain; } /* some other opening error */ ERR("Open error (%s): %s\n", pipe_name, strerror(errno)); goto error; } /* security checks: is this really a fifo?, is * it hardlinked? is it a soft link? */ if (fifo_check(fifofd, pipe_name) < 0) goto error; /* we want server blocking for big writes */ if ((flags = fcntl(fifofd, F_GETFL, 0)) < 0) { ERR("(%s): getfl failed: %s\n", pipe_name, strerror(errno)); goto error; } flags &= ~O_NONBLOCK; if (fcntl(fifofd, F_SETFL, flags) < 0) { ERR("(%s): setfl cntl failed: %s\n", pipe_name, strerror(errno)); goto error; } return fifofd; error: if (fifofd!=-1) close(fifofd); return -1; }
FILE *open_reply_pipe( char *pipe_name ) { int fifofd; FILE *file_handle; int flags; int retries=FIFO_REPLY_RETRIES; if (!pipe_name || *pipe_name==0) { DBG("DEBUG: open_reply_pipe: no file to write to about missing cmd\n"); return 0; } tryagain: /* open non-blocking to make sure that a broken client will not * block the FIFO server forever */ fifofd=open( pipe_name, O_WRONLY | O_NONBLOCK ); if (fifofd==-1) { /* retry several times if client is not yet ready for getting feedback via a reply pipe */ if (errno==ENXIO) { /* give up on the client - we can't afford server blocking */ if (retries==0) { LOG(L_ERR, "ERROR: open_reply_pipe: no client at %s\n", pipe_name ); return 0; } /* don't be noisy on the very first try */ if (retries!=FIFO_REPLY_RETRIES) DBG("DEBUG: open_reply_pipe: retry countdown: %d\n", retries ); sleep_us( FIFO_REPLY_WAIT ); retries--; goto tryagain; } /* some other opening error */ LOG(L_ERR, "ERROR: open_reply_pipe: open error (%s): %s\n", pipe_name, strerror(errno)); return 0; } /* security checks: is this really a fifo?, is * it hardlinked? is it a soft link? */ if (fifo_check(fifofd, pipe_name)<0) goto error; /* we want server blocking for big writes */ if ( (flags=fcntl(fifofd, F_GETFL, 0))<0) { LOG(L_ERR, "ERROR: open_reply_pipe (%s): getfl failed: %s\n", pipe_name, strerror(errno)); goto error; } flags&=~O_NONBLOCK; if (fcntl(fifofd, F_SETFL, flags)<0) { LOG(L_ERR, "ERROR: open_reply_pipe (%s): setfl cntl failed: %s\n", pipe_name, strerror(errno)); goto error; } /* create an I/O stream */ file_handle=fdopen( fifofd, "w"); if (file_handle==NULL) { LOG(L_ERR, "ERROR: open_reply_pipe: open error (%s): %s\n", pipe_name, strerror(errno)); goto error; } return file_handle; error: close(fifofd); return 0; }