void alive_thread(void *data) { while(1){ sleep(5); db_ping(); } }
int main (int argc, const char * argv[]) { // send_image_file(0,"/home/tube/Downloads/c1130-rcvk9w8-tar.124-25e.JAP.tar"); cw_log_name="AC-Tube"; read_config("ac.conf"); cw_log_debug_level=conf_debug_level; cw_log(LOG_INFO,"Starting AC-Tube, Name=%s, ID=%s",conf_acname,conf_acid); // cw_dbg_opt_level= DBG_CW_MSGELEM_DMP | // DBG_CW_MSGELEM | DBG_CW_PKT| DBG_CW_RFC | DBG_ERR | DBG_CW_MSG | DBG_DTLS ; //| DBG_ALL; cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP; // cw_log_dbg(DBG_CW_MSG,"Hello %s","World"); db_init(); db_start(); db_ping(); pthread_t alth; pthread_create (&alth, NULL, alive_thread, (void *)0); #ifdef WITH_DTLS dtls_init(); #endif if (!socklist_init()) goto errX; if (!wtplist_init()) goto errX; int rc = ac_run(); errX: wtplist_destroy(); socklist_destroy(); return rc; }
/** * The parser thread. This thread lives until a shutdown notification is received. It pulls * messages on a POSIX MQ based message queue containing submission ID and full path to an XML * report to be parsed. * * @param thrargs Contains database connection, XSLT stylesheet, POSXI MQ descriptor, etc * * @return Returns 0 on successful operation, otherwise 1 on errors. */ void *parsethread(void *thrargs) { threadData_t *args = (threadData_t *) thrargs; parseJob_t jobinfo; long exitcode = 0; writelog(args->dbc->log, LOG_DEBUG, "[Thread %i] Starting", args->id); pthread_mutex_lock(args->mtx_thrcnt); (*(args->threadcount)) += 1; pthread_mutex_unlock(args->mtx_thrcnt); // Polling loop while( *(args->shutdown) == 0 ) { int len = 0; unsigned int prio = 0; // Check if the database connection is alive before pulling any messages if( db_ping(args->dbc) != 1 ) { writelog(args->dbc->log, LOG_EMERG, "[Thread %i] Lost database conneciting: Shutting down thread.", args->id); if( *(args->threadcount) <= 1 ) { writelog(args->dbc->log, LOG_EMERG, "No more worker threads available. " "Signaling for complete shutdown!"); kill(getpid(), SIGUSR1); } exitcode = 1; goto exit; } // Retrieve a parse job from the message queue memset(&jobinfo, 0, sizeof(parseJob_t)); errno = 0; len = mq_receive(args->msgq, (char *)&jobinfo, sizeof(parseJob_t), &prio); if( (len < 0) && errno != EAGAIN ) { writelog(args->dbc->log, LOG_CRIT, "Could not receive the message from queue: %s", strerror(errno)); pthread_exit((void *) 1); } // Ignore whatever message if the shutdown flag is set. if( *(args->shutdown) != 0 ) { break; } // If we have a message, then process the parse job if( (errno != EAGAIN) && (len > 0) ) { int res = 0; writelog(args->dbc->log, LOG_INFO, "[Thread %i] Job recieved, submid: %i - %s", args->id, jobinfo.submid, jobinfo.filename); // Mark the job as "in progress", if successful update, continue parsing it if( db_update_submissionqueue(args->dbc, jobinfo.submid, STAT_INPROG) ) { res = parse_report(args, &jobinfo); // Set the status for the submission db_update_submissionqueue(args->dbc, jobinfo.submid, res); } else { writelog(args->dbc->log, LOG_CRIT, "Failed to mark submid %i as STAT_INPROG", jobinfo.submid); } } } writelog(args->dbc->log, LOG_DEBUG, "[Thread %i] Shut down", args->id); exit: pthread_mutex_lock(args->mtx_thrcnt); (*(args->threadcount)) -= 1; pthread_mutex_unlock(args->mtx_thrcnt); pthread_exit((void *) exitcode); }
/** * Main loop, which polls the submissionqueue table and puts jobs found here into a POSIX MQ queue * which the worker threads will pick up. * * @param dbc Database connection, where to query the submission queue * @param msgq file descriptor for the message queue * @param activethreads Pointer to an int value containing active worker threads. Each thread updates * this value directly, and this function should only read it. * * @return Returns 0 on successful run, otherwise > 0 on errors. */ int process_submission_queue(dbconn *dbc, mqd_t msgq, int *activethreads) { pthread_mutex_t mtx_submq = PTHREAD_MUTEX_INITIALIZER; parseJob_t *job = NULL; int rc = 0, i, actthr_cp = 0; while( shutdown == 0 ) { // Check status if the worker threads // If we don't have any worker threads, shut down immediately writelog(dbc->log, LOG_DEBUG, "Active worker threads: %i", *activethreads); if( *activethreads < 1 ) { writelog(dbc->log, LOG_EMERG, "All worker threads ceased to exist. Shutting down!"); shutdown = 1; rc = 1; goto exit; } if( db_ping(dbc) != 1 ) { writelog(dbc->log, LOG_EMERG, "Lost connection to database. Shutting down!"); shutdown = 1; rc = 1; goto exit; } // Fetch an available job job = db_get_submissionqueue_job(dbc, &mtx_submq); if( !job ) { writelog(dbc->log, LOG_EMERG, "Failed to get submission queue job. Shutting down!"); shutdown = 1; rc = 1; goto exit; } if( job->status == jbNONE ) { free_nullsafe(job); if( db_wait_notification(dbc, &shutdown, "rteval_submq") < 1 ) { writelog(dbc->log, LOG_EMERG, "Failed to wait for DB notification. Shutting down!"); shutdown = 1; rc = 1; goto exit; } continue; } // Send the job to the queue writelog(dbc->log, LOG_DEBUG, "** New job queued: submid %i, %s", job->submid, job->filename); do { int res; errno = 0; res = mq_send(msgq, (char *) job, sizeof(parseJob_t), 1); if( (res < 0) && (errno != EAGAIN) ) { writelog(dbc->log, LOG_EMERG, "Could not send parse job to the queue. " "Shutting down!"); shutdown = 1; rc = 2; goto exit; } else if( errno == EAGAIN ) { writelog(dbc->log, LOG_WARNING, "Message queue filled up. " "Will not add new messages to queue for the next 60 seconds"); sleep(60); } } while( (errno == EAGAIN) ); free_nullsafe(job); } exit: // Send empty messages to the threads, to make them have a look at the shutdown flag job = (parseJob_t *) malloc_nullsafe(dbc->log, sizeof(parseJob_t)); errno = 0; // Need to make a copy, as *activethreads will change when threads completes shutdown actthr_cp = *activethreads; for( i = 0; i < actthr_cp; i++ ) { do { int res; writelog(dbc->log, LOG_DEBUG, "%s shutdown message %i of %i", (errno == EAGAIN ? "Resending" : "Sending"), i+1, *activethreads); errno = 0; res = mq_send(msgq, (char *) job, sizeof(parseJob_t), 1); if( (res < 0) && (errno != EAGAIN) ) { writelog(dbc->log, LOG_EMERG, "Could not send shutdown notification to the queue."); free_nullsafe(job); return rc; } else if( errno == EAGAIN ) { writelog(dbc->log, LOG_WARNING, "Message queue filled up. " "Will not add new messages to queue for the next 10 seconds"); sleep(10); } } while( (errno == EAGAIN) ); } free_nullsafe(job); return rc; }