static THREAD_FUNC ServiceThread(void *argptr) { CLIENT *client; static char *fid = "ServiceThread"; client = (CLIENT *) argptr; LogMsg(LOG_DEBUG, "%s: thread started, id = 0x%x", fid, THREAD_SELF()); while (!client->finished) { if (iacpRecvFrame(client->iacp, &client->recv.frame, client->recv.buf, client->recv.buflen)) { /* Make sure signature is OK */ if (!client->recv.frame.auth.verified) { LogMsg(LOG_ERR, "%s: authentication failed", client->ident); iacpSendAlert(client->iacp, IACP_ALERT_FAILED_AUTH); client->finished = TRUE; } /* Save a copy of this message for status reports */ if (client->recv.frame.payload.type != IACP_TYPE_NULL) { client->last.msg.type = client->recv.frame.payload.type; client->last.msg.len = client->recv.frame.payload.len; memcpy(client->last.msg.data, client->recv.frame.payload.data, client->recv.frame.payload.len); } /* Respond to the message */ RespondToClientMessage(client); } else { LogRecvError(client->iacp); if (iacpGetRecvError(client->iacp) != ETIMEDOUT) iacpSendAlert(client->iacp, IACP_ALERT_IO_ERROR); client->finished = TRUE; } } CloseClientConnection(client); LogMsg(LOG_DEBUG, "%s: thread 0x%x exits", fid, THREAD_SELF()); THREAD_EXIT((void *) 0); }
static THREAD_FUNC StatusServer(void *argptr) { FILE *fp; UINT16 port; int sd, peer; struct sockaddr_in serv_addr, cli_addr; int yes = 1, ilen = sizeof(int), clen = sizeof(cli_addr); static char *fid = "StatusServer"; LogMsg(LOG_DEBUG, "%s: thread started, id = %d", fid, THREAD_SELF()); /* Create socket and bind */ port = *((UINT16 *) argptr); if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { LogMsg(LOG_ERR, "%s: socket: %s", fid, strerror(errno)); GracefulExit(MY_MOD_ID + 1); } memset((void *) &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, ilen); if (bind( sd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) != 0) { LogMsg(LOG_ERR, "%s: bind: %s", fid, strerror(errno)); GracefulExit(MY_MOD_ID + 2); } /* Start listening for connectinos */ if (listen(sd, 5) != 0) { LogMsg(LOG_ERR, "%s: listen: %s", fid, strerror(errno)); GracefulExit(MY_MOD_ID + 3); } /* Service one connection at a time */ LogMsg(LOG_INFO, "listening for status requests at port %hu", port); while (1) { peer = INVALID_SOCKET; while (peer == INVALID_SOCKET) { peer = accept(sd, (struct sockaddr *) &cli_addr, &clen); if (peer == INVALID_SOCKET && errno != EINTR) { LogMsg(LOG_ERR, "%s: accept: %s (ignored)", fid, strerror(errno)); } else { if ((fp = fdopen(peer, "w")) == NULL) { LogMsg(LOG_ERR, "%s: fdopen: %s", fid, strerror(errno)); } else { PrintStatusReport(fp); fclose(fp); } shutdown(peer, 2); close(peer); } } } }
THREAD_FUNC AuxDataToIDA8Thread(void *argptr) { long *out; int nsamp; OLD_MSGQ_MSG *SampleMsg, *BufferMsg; ISPD_AUX_DATUM sample; ISPD_AUX_HANDLE *ap; static char *fid = "AuxDataToIDA8Thread"; util_log(2, "%s thread started, tid = %d", fid, THREAD_SELF()); ap = (ISPD_AUX_HANDLE *) argptr; nsamp = 0; while (1) { /* Grap the next aux sample */ SampleMsg = msgq_get(ap->q.full, OLD_MSGQ_WAITFOREVER); if (!msgq_chkmsg2(fid, SampleMsg)) { util_log(1, "%s: corrupt message received", fid); ispd_die(MY_MOD_ID + 4); } /* Copy it to local storage */ sample = *((ISPD_AUX_DATUM *) SampleMsg->data); msgq_put(ap->q.empty, SampleMsg); /* If starting a new packet, grab empty buffer from heap and init */ if (nsamp == 0) { BufferMsg = msgq_get(&Heap->packets, OLD_MSGQ_WAITFOREVER); if (!msgq_chkmsg2(fid, BufferMsg)) { util_log(1, "%s: corrupt message received", fid); ispd_die(MY_MOD_ID + 1); } out = (long *) StartIDA8Packet(ap, &sample, BufferMsg->data); } /* Append uncompressed samples to packet until done */ out[nsamp++] = htonl(sample.value); if (nsamp == MAXSAMP) { FinishIDA8Packet(ap, nsamp, &sample, BufferMsg->data); msgq_put(&Q->das_process, BufferMsg); MUTEX_LOCK(&Status->lock); ++ap->stat->nrec; MUTEX_UNLOCK(&Status->lock); nsamp = 0; } } }
THREAD_FUNC ttyioReadThread(void *argptr) { TTYIO *tp; COMSTAT ComStat; DWORD dwErrFlags; DWORD rcvd=0, sent=0; BOOL done = FALSE; static char *fid = "ttyioReadThread"; tp = (TTYIO *) argptr; logioMsg(tp->lp, LOG_DEBUG, "%s: thread started id=%d", fid, THREAD_SELF()); SEM_POST(&tp->pipe.semaphore); while (1) { ClearCommError(tp->fd, &dwErrFlags, &ComStat); if (!ReadFile(tp->fd, (char *) tp->pipe.buf, (DWORD) tp->attr.at_pipe, &rcvd, 0)) { logioMsg(tp->lp, LOG_INFO, "%s: ReadFile: %s", fid, strerror(errno)); MUTEX_LOCK(&tp->mutex); done = tp->pipe.failed = TRUE; MUTEX_UNLOCK(&tp->mutex); } else if (rcvd > 0) { if (!WriteFile(tp->pipe.in, (char *) tp->pipe.buf, rcvd, &sent, 0)) { logioMsg(tp->lp, LOG_INFO, "%s: WriteFile: %s", fid, strerror(errno)); MUTEX_LOCK(&tp->mutex); done = tp->pipe.failed = TRUE; MUTEX_UNLOCK(&tp->mutex); } } else { sent = 0; Sleep(25); } if (done) { MUTEX_LOCK(&tp->mutex); tp->pipe.active = FALSE; MUTEX_UNLOCK(&tp->mutex); SEM_POST(&tp->pipe.semaphore); THREAD_EXIT(0); } } }
static void *SignalHandlerThread(void *dummy) { sigset_t set; int sig; static char *fid = "SignalHandlerThread"; util_log(2, "Signal handler started, tid = %d", THREAD_SELF()); sigfillset(&set); /* catch all signals defined by the system */ while (1) { /* wait for a signal to arrive */ sigwait(&set, &sig); /* process signals */ if (sig == SIGHUP) { util_log(2, "%s", util_sigtoa(sig)); #ifdef DEBUG_MSGQS ShowMessageQueues(); #endif if (OutputMediaType() != ISP_OUTPUT_TAPE) UpdateCdStats(FALSE); } else if (sig == SIGUSR1) { LogMsg(LOG_INFO, "%s", util_sigtoa(sig)); LogMsgLevel(LOG_DEBUG); } else if (sig == SIGUSR2) { LogMsg(LOG_INFO, "%s", util_sigtoa(sig)); LogMsgLevel(LOG_INFO); nrtsToggleCheckTstampLoggingFlag(); } else if (sig == SIGINT || sig == SIGTERM || sig == SIGQUIT) { LogMsg(LOG_INFO, "%s", util_sigtoa(sig)); ispd_die(MY_MOD_ID + 0); } else { LogMsg(LOG_INFO, "%s", util_sigtoa(sig)); LogMsg(LOG_INFO, "signal ignored"); } } }
/*====================================================================== Purpose: Purge thread main loop. Returns: Notes: Revised: 15Dec04 (pld) use SEM_TRYWAIT() to clear semiphore after purge to prevent purging more than needed (several SEM_POST() calls while doing purge) ----------------------------------------------------------------------*/ THREAD_FUNC PurgeThread(VOID *argument) { PURGE *purge; ASSERT(argument != NULL); purge = (PURGE *)argument; MUTEX_LOCK(&purge->mutex); purge->active = TRUE; purge->stop = FALSE; MUTEX_UNLOCK(&purge->mutex); ArchiveLog(ARC_LOG_VERBOSE, "PurgeThread start, tid: %u, pid %u", THREAD_SELF(), getpid()); while (TRUE) { SEM_WAIT(&purge->semaphore); if (purge->stop) break; ArchiveLog(ARC_LOG_VERBOSE, "Archive: purge initiated"); if (!Purge(purge->handle)) break; while (SEM_TRYWAIT(&purge->semaphore) == 0) ; } ArchiveLog(ARC_LOG_VERBOSE, "PurgeThread exit"); MUTEX_LOCK(&purge->mutex); purge->active = FALSE; MUTEX_UNLOCK(&purge->mutex); THREAD_EXIT((VOID*)0); } /* end PurgeThread() */
static THREAD_FUNC TapeWatchThread(void *dummy) { int boot_flag; static struct mtget info; static char *fid = "TapeWatchThread"; boot_flag = 1; util_log(2, "TAPE_WATCH thread started, tid = %d", THREAD_SELF()); set_alarm(ISP_ALARM_OFFLINE); while (1) { MUTEX_LOCK(&mp); /* if we were offline, see if a tape is now present */ if (prev_state == MTIO_OFFLINE) { if ((tp = mtio_open(Params->odev, "w")) != null) { if (mtio_status(tp, &info) != -1) { crnt_state = MTIO_ONLINE; clear_alarm(ISP_ALARM_OFFLINE); if (ioerr) { clear_alarm(ISP_ALARM_IOERR); ioerr = 0; } check_tape(boot_flag); } else { mtio_close(tp); tp = (TAPE *) NULL; } } if (tp == null && shutting_down()) { util_log(1, "shutting down w/o final flush (no tape)"); complete_shutdown(); } /* if we were on-line, make sure we still are that way */ /* THIS CODE DOES NOT WORK AND I DON'T KNOW HOW TO MAKE IT WORK! */ } else if (mtio_nop(tp) < 0 || mtio_status(tp, &info) < 0) { mtio_close(tp); tp = (TAPE *) tp; set_alarm(ISP_ALARM_OFFLINE); crnt_state = MTIO_OFFLINE; } if (crnt_state != prev_state) { MUTEX_LOCK(&Status->lock); if (crnt_state == MTIO_ONLINE) { Status->output.state = ISP_OUTPUT_ONLINE; Status->output.err = 0; Status->output.file = info.mt_fileno + 1; Status->output.nrec = 0; } else { Status->output.state = ISP_OUTPUT_OFFLINE; } MUTEX_UNLOCK(&Status->lock); } prev_state = crnt_state; boot_flag = 0; if (pending && (crnt_state == MTIO_ONLINE)) { pending = 0; SEM_POST(&sp); } MUTEX_UNLOCK(&mp); sleep(10); } }