static THREAD_FUNC ServerThread(void *arg) { u_short port; struct sockaddr_in cli_addr; #ifdef socklen_t socklen_t len = sizeof(cli_addr); #else int len = sizeof(cli_addr); #endif static char *fid = "isp_inject:ServerThread"; port = *((u_short *) arg); util_log(1, "ISP injection service installed at port %hd", port); /* Wait for connections */ while (1) { client = accept(sd, (struct sockaddr *) &cli_addr, &len); if (client < 0 && errno != EINTR) { util_log(1, "%s: accept: %s", fid, syserrmsg(errno)); util_log(1, "isp injection service aborted"); THREAD_EXIT(0); } else if (client >= 0) { ServiceConnection(); shutdown(client, 2); close(client); client = 0; } } }
/* Since we don't want any of the worker threads to catch any signals, we must mask off any * potential signals here after creating the threads. If any of the created threads catch a signal, * they'd eventually call join on themselves, causing a deadlock. */ void thread_signal_init() { sigset_t thread_sigmask; int rc; if ((rc = sigfillset(&thread_sigmask))) { LogError("sigfillset failed: error=%d: %s", rc, strerror(rc)); LogError("worker thread %ld is exiting prematurely", THREAD_ID); THREAD_EXIT(NULL); } if ((rc = THREAD_SET_SIGNAL_MASK(SIG_BLOCK, &thread_sigmask, NULL))) { LogError("Setting thread sigmask failed: error=%d: %s", rc, strerror(rc)); LogError("worker thread %ld is exiting prematurely", THREAD_ID); THREAD_EXIT(NULL); } }
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); }
void *rt_matrixmul(void *data) { unsigned int ret; int **ret2; int flag; while (1) { flag = 0; while(!flag){ flag = MBOX_TRYGET(resources_address,ret); } if (ret == UINT_MAX) { THREAD_EXIT(); } ret2 = (int **)ret; std_matrix_mul(ret2[0], ret2[1], ret2[2], STD_MMP_MATRIX_SIZE); MBOX_PUT(resources_acknowledge, (int)ret2[2]); } return NULL; }
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); } } }
/*====================================================================== 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 TapeWriteThread(void *dummy) { int status; size_t blen, remain, want, put, nrec; char *ptr; OLD_MSGQ_MSG *obuf; static char *fid = "TapeWriteThread"; blen = Params->bfact * IDA_BUFSIZ; /* IDA10 OK */ MUTEX_LOCK(&mp); ioerr = 0; MUTEX_UNLOCK(&mp); while (1) { obuf = msgq_get(&Q->obuf, OLD_MSGQ_WAITFOREVER); if (!msgq_chkmsg2(fid, obuf)) { util_log(1, "%s: corrupt message received", fid); ispd_die(MY_MOD_ID + 1); } nrec = *((size_t *) obuf->data); util_log(1, "dumping %ld records to %s", nrec, Params->odev); ptr = obuf->data + sizeof(size_t); remain = nrec * IDA_BUFSIZ; /* IDA10 OK */ while (remain > 0) { want = remain > blen ? blen : remain; nrec = want / IDA_BUFSIZ; /* IDA10 OK */ do { lock_device(); put = mtio_write(tp, ptr, want); if (put == want) { MUTEX_LOCK(&Status->lock); Status->output.nrec += nrec; status = Status->output.state; MUTEX_UNLOCK(&Status->lock); ptr += put; if (ioerr) { clear_alarm(ISP_ALARM_IOERR); ioerr = 0; } } else { if (put != 0) { if (++ioerr == 1) { set_alarm(ISP_ALARM_IOERR); util_log(1, "%s: %s", Params->odev, syserrmsg(errno) ); } MUTEX_LOCK(&Status->lock); ++Status->output.err; MUTEX_UNLOCK(&Status->lock); eject_tape(0); } } release_device(); if (put != want) { if (shutting_down()) { complete_shutdown(); THREAD_EXIT(0); } else { sleep(5); } } } while (put != want); remain -= put; } util_log(1, "tape dump completed OK"); if (shutting_down()) { complete_shutdown(); THREAD_EXIT(0); } MUTEX_LOCK(&mp); if (eject_flag) eject_tape(0); eject_flag = 0; MUTEX_UNLOCK(&mp); msgq_put(&Heap->obuf, obuf); } }
void * tcsd_thread_run(void *v) { struct tcsd_thread_data *data = (struct tcsd_thread_data *)v; BYTE buffer[TCSD_TXBUF_SIZE]; struct tcsd_packet_hdr *ret_buf = NULL; TSS_RESULT result; int sizeToSend, sent_total, sent; UINT64 offset; #ifndef TCSD_SINGLE_THREAD_DEBUG int rc; thread_signal_init(); #endif if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) { LogError("Failed Receive: %s", strerror(errno)); goto done; } LogDebug("Rx'd packet"); data->buf = buffer; while (1) { sent_total = 0; if (data->buf_size > TCSD_TXBUF_SIZE) { LogError("Packet received from socket %d was too large (%u bytes)", data->sock, data->buf_size); goto done; } else if (data->buf_size < (int)((2 * sizeof(UINT32)) + sizeof(UINT16))) { LogError("Packet received from socket %d was too small (%u bytes)", data->sock, data->buf_size); goto done; } if ((result = getTCSDPacket(data, &ret_buf)) != TSS_SUCCESS) { /* something internal to the TCSD went wrong in preparing the packet * to return to the TSP. Use our already allocated buffer to return a * TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path, * these LoadBlob's are done in getTCSDPacket(). */ offset = 0; /* load result */ LoadBlob_UINT32(&offset, result, buffer); /* load packet size */ LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), buffer); /* load num parms */ LoadBlob_UINT16(&offset, 0, buffer); sizeToSend = sizeof(struct tcsd_packet_hdr); LogDebug("Sending 0x%X bytes back", sizeToSend); while (sent_total < sizeToSend) { if ((sent = send(data->sock, &data->buf[sent_total], sizeToSend - sent_total, 0)) < 0) { LogError("Packet send to TSP failed: send: %s. Thread exiting.", strerror(errno)); goto done; } sent_total += sent; } } else { sizeToSend = Decode_UINT32((BYTE *)&(ret_buf->packet_size)); LogDebug("Sending 0x%X bytes back", sizeToSend); while (sent_total < sizeToSend) { if ((sent = send(data->sock, &(((BYTE *)ret_buf)[sent_total]), sizeToSend - sent_total, 0)) < 0) { LogError("response to TSP failed: send: %s. Thread exiting.", strerror(errno)); free(ret_buf); ret_buf = NULL; goto done; } sent_total += sent; } free(ret_buf); ret_buf = NULL; } if (tm->shutdown) { LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID); break; } /* receive the next packet */ if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) { LogError("TSP has closed its connection: %s. Thread exiting.", strerror(errno)); break; } else if (data->buf_size == 0) { LogDebug("The TSP has closed the socket's connection. Thread exiting."); break; } } done: /* Closing connection to TSP */ close(data->sock); data->sock = -1; data->buf = NULL; data->buf_size = -1; /* If the connection was not shut down cleanly, free TCS resources here */ if (data->context != NULL_TCS_HANDLE) { TCS_CloseContext_Internal(data->context); data->context = NULL_TCS_HANDLE; } #ifndef TCSD_SINGLE_THREAD_DEBUG MUTEX_LOCK(tm->lock); tm->num_active_threads--; /* if we're not in shutdown mode, then nobody is waiting to join this thread, so * detach it so that its resources are free at THREAD_EXIT() time. */ if (!tm->shutdown) { if ((rc = THREAD_DETACH(*(data->thread_id)))) { LogError("Thread detach failed (errno %d)." " Resources may not be properly released.", rc); } } free(data->hostname); data->hostname = NULL; data->thread_id = THREAD_NULL; MUTEX_UNLOCK(tm->lock); THREAD_EXIT(NULL); #else return NULL; #endif }
int main(int argc, char **argv) { int i; int timeout = 10; int si = 1; int debug = 0; THREAD tid; char *pwd, *sta = NULL; char RunFile[MAXPATHLEN+1], *log = (char *) NULL; static char LogFile[MAXPATHLEN+1]; static char *default_server = "localhost"; ISP_SERVER ispd; time_t idle = 600; server = default_server; for (i = 1; i < argc; i++) { if (strncasecmp(argv[i], "home=", strlen("home=")) == 0) { home = argv[i] + strlen("home="); } else if (strncasecmp(argv[i], "sta=", strlen("sta=")) == 0) { sta = argv[i] + strlen("sta="); } else if (strncasecmp(argv[i], "debug=", strlen("debug=")) == 0) { debug = atoi(argv[i] + strlen("debug=")); } else if (strncasecmp(argv[i], "idle=", strlen("idle=")) == 0) { idle = atoi(argv[i] + strlen("idle=")); } else if (strcasecmp(argv[i], "-h") == 0) { help(argv[0]); } else if (strcasecmp(argv[i], "help") == 0) { help(argv[0]); } else if (sta == (char *) NULL) { sta = argv[i]; } else { help(argv[0]); } } SetMaxIdle(idle); if ((pwd = isp_setup(&home, &sta)) == (char *) NULL) exit(1); if ((Syscode = strdup(sta)) == NULL) { perror(argv[0]); exit(1); } util_lcase(Syscode); sprintf(RunFile, "%s/%s", pwd, ISP_RUN_FILE); if (!ispLoadRunParam(RunFile, sta, NULL, &ispd)) { fprintf(stderr, "%s: problems with parameter file\n", argv[0]); exit(1); } if (debug) util_logopen("syslogd", 1, 9, debug, "CONSOLE", argv[0]); console = (getppid() == 1); if (console) util_log(1, "Running as BOOT CONSOLE"); /* Start signal handling thread */ InitSignals(); /* Allocate space for channel map */ InitChanMap(); /* Initialize the display */ sprintf(LogFile, "%s/log/nrtslog", home); if (OpenDisplay(server, ispd.port, LogFile) != 0) { fprintf(stderr, "%s: ABORT: Can't open display\n", argv[0]); sleep(1); Quit(1); } /* Connect to the server */ ServerConnect(server, ispd.port, ispd.to, TRUE); /* Start status request thread */ util_log(1, "Start routine status requests"); if (!THREAD_CREATE(&tid, StatusRequest, NULL)) { EndWin(); fprintf(stderr, "failed to create StatusRequest thread\n"); exit(1); } /* Start interactive thread */ util_log(1, "Start interactive display"); FirstDisplay(); while (1) { switch (Digitizer()) { case ISP_DAS: util_log(1, "ISP_DAS detected, start DasDisplay"); if (!THREAD_CREATE(&tid, DasDisplay, NULL)) { EndWin(); fprintf(stderr, "failed to create DasDisplay thread\n"); exit(1); } THREAD_EXIT(0); case ISP_SAN: util_log(1, "ISP_San detected, start SanDisplay"); if (!THREAD_CREATE(&tid, SanDisplay, NULL)) { EndWin(); fprintf(stderr, "failed to create SanDisplay thread\n"); exit(1); } THREAD_EXIT(0); default: sleep(1); } } }