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; } } }
lookup_main(int request_fd[2], int result_fd[2]) { MsgQ *request_mq; MsgQ *result_mq; struct sigaction sigact; close(request_fd[1]); close(result_fd[0]); request_mq = msgq_new(request_fd[0]); result_mq = msgq_new(result_fd[1]); /* Inability to register these signals is not a fatal error. */ sigact.sa_flags = SA_RESTART; sigact.sa_handler = SIG_IGN; #ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER sigact.sa_restorer = NULL; #endif sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGUSR1, &sigact, NULL); sigaction(SIGCHLD, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); while (msgq_read_complete_msg(request_mq) > 0) { char *node; char *service; void *data; size_t size; struct addrinfo *hints_ai; struct addrinfo *result_ai = NULL; int rc; /* XXX: msgq_get_sync, check its result, and use for (;;) */ msgq_get(request_mq, MSGQ_STR, &node, MSGQ_STR, &service, MSGQ_BLOB, &data, &size, MSGQ_END); hints_ai = data_to_addrinfo(data, size); rc = getaddrinfo(node, service, hints_ai, &result_ai); free(node); free(service); free_read_addrinfo(hints_ai); free(data); addrinfo_to_data(result_ai, &data, &size); /* XXX: msgq_put_sync, check its result, and get rid of msgq_write_all */ msgq_put(result_mq, MSGQ_INT, rc, MSGQ_BLOB, data, size, MSGQ_END); free(data); if (msgq_write_all(result_mq) < 0) break; } /* msgq_read_complete_msg may have failed if it returned < 0. * But we can't print any errors from this process (it would * interfere with the readline-managed display, so just exit * gracefully. */ msgq_free(request_mq); msgq_free(result_mq); close(request_fd[0]); close(result_fd[1]); exit(EXIT_SUCCESS); }
void * writer_start(void * usr) { uint32_t msg[2] = {WORK, 10}; while(1) { msgq_put(replyq, msg, sizeof(msg)); } return 0; }
static void ServiceConnection() { char peer[IDA_MAXRECLEN]; char empty[IDA_MAXRECLEN]; int done, count; OLD_MSGQ_MSG *msg; OLD_MSGQ *dest; static char *fid = "isp_inject:ServceConnection"; util_peer(client, peer, IDA_MAXRECLEN); util_log(1, "injection request from %s", peer); memset(empty, 0, IDA_MAXRECLEN); util_noblock(client); done = count = 0; while (!done) { msg = msgq_get(&Heap->packets, OLD_MSGQ_WAITFOREVER); if (!msgq_chkmsg2(fid, msg)) { util_log(1, "%s: corrupt Heap->packets message received", fid); ispd_die(MY_MOD_ID + 1); } if (util_read(client, msg->data, IDA_BUFSIZ, 10) == IDA_BUFSIZ) { /* IDA10 OK */ if (memcmp(msg->data, empty, IDA_BUFSIZ) == 0) { /* IDA10 OK */ done = 1; dest = &Heap->packets; } else { ++count; MUTEX_LOCK(&Status->lock); ++Status->count.njec; MUTEX_UNLOCK(&Status->lock); dest = &Q->das_process; } } else { util_log(1, "read error from %s: %s", peer, syserrmsg(errno)); done = 1; dest = &Heap->packets; } msgq_put(dest, msg); } util_log(1, "%d records received from %s", count, peer); }
DCLookup * add_lookup_request(const char *node, const char *service, const struct addrinfo *hints, DCLookupCallback callback, void *userdata) { void *data; size_t size; DCLookup *lookup; addrinfo_to_data(hints, &data, &size); msgq_put(lookup_request_mq, MSGQ_STR, node, MSGQ_STR, service, MSGQ_BLOB, data, size, MSGQ_END); free(data); FD_SET(lookup_request_mq->fd, &write_fds); lookup = (DCLookup*) xmalloc(sizeof(DCLookup)); lookup->callback = callback; lookup->data = userdata; lookup->cancelled = false; ptrv_append(pending_lookups, lookup); return lookup; }
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); } }
static void user_result_fd_readable(DCUserConn *uc) { int res; res = msgq_read(uc->get_mq); if (res == 0 || (res < 0 && errno != EAGAIN)) { warn_socket_error(res, false, _("user process %s"), quote(uc->name)); user_disconnect(uc); /* MSG: socket error above */ return; } while (msgq_has_complete_msg(uc->get_mq)) { int id; msgq_peek(uc->get_mq, MSGQ_INT, &id, MSGQ_END); switch (id) { case DC_MSG_SCREEN_PUT: { char *msg; uint32_t flag; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT32, &flag, MSGQ_STR, &msg, MSGQ_END); flag_putf((DCDisplayFlag)flag, _("User %s: %s"), quotearg(uc->name), msg); /* msg already quoted */ free(msg); break; } case DC_MSG_WANT_DOWNLOAD: { bool reply; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END); reply = !has_user_conn(uc->info, DC_DIR_RECEIVE) && (uc->queue_pos < uc->info->download_queue->cur); msgq_put(uc->put_mq, MSGQ_BOOL, reply, MSGQ_END); FD_SET(uc->put_mq->fd, &write_fds); break; } case DC_MSG_VALIDATE_DIR: { DCTransferDirection dir; bool reply; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT, &dir, MSGQ_END); reply = validate_direction(uc, dir); msgq_put(uc->put_mq, MSGQ_BOOL, reply, MSGQ_END); FD_SET(uc->put_mq->fd, &write_fds); break; } case DC_MSG_VALIDATE_NICK: { char *nick; bool reply; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_STR, &nick, MSGQ_END); reply = validate_nick(uc, nick); free(nick); if (uc->info != NULL) { /* The user can only be DC_ACTIVE_SENT_PASSIVE if we are passive. * So if we managed to connect to them even though we were passive, * they must be active. */ if (uc->info->active_state == DC_ACTIVE_SENT_PASSIVE) uc->info->active_state = DC_ACTIVE_KNOWN_ACTIVE; /* The user can only be DC_ACTIVE_SENT_ACTIVE if we are active. * We must set to DC_ACTIVE_UNKNOWN because otherwise * hub.c:hub_connect_user might say "ConnectToMe already sent to * user" next time we're trying to connect to them. */ if (uc->info->active_state == DC_ACTIVE_SENT_ACTIVE) uc->info->active_state = DC_ACTIVE_UNKNOWN; } msgq_put(uc->put_mq, MSGQ_BOOL, reply, MSGQ_END); FD_SET(uc->put_mq->fd, &write_fds); break; } case DC_MSG_GET_MY_NICK: msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END); msgq_put(uc->put_mq, MSGQ_STR, my_nick, MSGQ_END); FD_SET(uc->put_mq->fd, &write_fds); break; case DC_MSG_TRANSFER_STATUS: msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT64, &uc->transfer_pos, MSGQ_END); break; case DC_MSG_TRANSFER_START: { char *share_filename, *local_filename; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_STR, &local_filename, MSGQ_STR, &share_filename, MSGQ_INT64 , &uc->transfer_start, MSGQ_INT64, &uc->transfer_total, MSGQ_END); if (uc->transfer_start != 0) { flag_putf(DC_DF_CONNECTIONS, _("%s: Starting %s of %s (%" PRIu64 " of %" PRIu64 " %s).\n"), quotearg_n(0, uc->info->nick), uc->dir == DC_DIR_SEND ? _("upload") : _("download"), quote_n(1, base_name(share_filename)), uc->transfer_total - uc->transfer_start, uc->transfer_total, ngettext("byte", "bytes", uc->transfer_total)); } else { flag_putf(DC_DF_CONNECTIONS, _("%s: Starting %s of %s (%" PRIu64 " %s).\n"), quotearg_n(0, uc->info->nick), uc->dir == DC_DIR_SEND ? _("upload") : _("download"), quote_n(1, base_name(share_filename)), uc->transfer_total, ngettext("byte", "bytes", uc->transfer_total)); } free(uc->transfer_file); uc->transfer_file = share_filename; free(uc->local_file); uc->local_file = local_filename; uc->transferring = true; uc->transfer_pos = uc->transfer_start; uc->transfer_time = time(NULL); if (uc->transfer_time == (time_t) -1) warn(_("Cannot get current time - %s\n"), errstr); break; } case DC_MSG_CHECK_DOWNLOAD: msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END); for (; uc->queue_pos < uc->info->download_queue->cur; uc->queue_pos++) { DCQueuedFile *queued; char *local_file; queued = (DCQueuedFile*) uc->info->download_queue->buf[uc->queue_pos]; if (queued->status != DC_QS_DONE) { local_file = resolve_download_file(uc->info, queued); uc->queued_valid = true; uc->transfer_file = xstrdup(queued->filename); uc->local_file = xstrdup(local_file); uc->occupied_slot = true; queued->status = DC_QS_PROCESSING; used_dl_slots++; msgq_put(uc->put_mq, MSGQ_STR, local_file, MSGQ_STR, uc->transfer_file, MSGQ_INT64, queued->length, MSGQ_INT, queued->flag, MSGQ_END); FD_SET(uc->put_mq->fd, &write_fds); free(local_file); return; } } msgq_put(uc->put_mq, MSGQ_STR, NULL, MSGQ_STR, NULL, MSGQ_INT64, (uint64_t) 0, MSGQ_INT, DC_TF_NORMAL, MSGQ_END); FD_SET(uc->put_mq->fd, &write_fds); break; case DC_MSG_DOWNLOAD_ENDED: { bool success; char *reason; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_BOOL, &success, MSGQ_STR, &reason, MSGQ_END); handle_ended_download(uc, success, reason); free(reason); break; } case DC_MSG_CHECK_UPLOAD: { char *remote_file; char *local_file; int type; uint64_t size = 0; DCTransferFlag flag = DC_TF_NORMAL; bool permit_transfer = false; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT, &type, MSGQ_STR, &remote_file, MSGQ_END); local_file = (char*) resolve_upload_file(uc->info, (DCAdcgetType) type, remote_file, &flag, &size); free(remote_file); uc->transfer_file = NULL; if (local_file != NULL) { if (flag == DC_TF_LIST || (flag == DC_TF_NORMAL && size <= minislot_size)) { if (used_mini_slots < minislot_count) { used_mini_slots ++; uc->occupied_minislot = true; permit_transfer = true; } else if (used_ul_slots < my_ul_slots || uc->info->slot_granted) { used_ul_slots ++; uc->occupied_slot = true; permit_transfer = true; } } else if (flag == DC_TF_NORMAL && size > minislot_size) { if (used_ul_slots < my_ul_slots || uc->info->slot_granted) { used_ul_slots ++; uc->occupied_slot = true; permit_transfer = true; } } if (permit_transfer) { uc->transfer_file = local_file; } else { free(local_file); local_file = NULL; } } else { permit_transfer = true; } msgq_put(uc->put_mq, MSGQ_BOOL, permit_transfer, MSGQ_STR, local_file, MSGQ_END); FD_SET(uc->put_mq->fd, &write_fds); break; } case DC_MSG_UPLOAD_ENDED: { bool success; char *reason; msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_BOOL, &success, MSGQ_STR, &reason, MSGQ_END); handle_ended_upload(uc, success, reason); free(reason); break; } case DC_MSG_TERMINATING: /* The TERMINATING message will be sent from users when they're about to * shut down properly. * XXX: This message may contain the reason it was terminated in the future. */ msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END); user_disconnect(uc); /* MSG: reason from DC_MSG_TERMINATING */ return; /* not break! this is the last message. */ default: warn(_("Received unknown message %d from user process, shutting down process.\n"), id); user_disconnect(uc); /* MSG: local communication error? */ return; /* not break! this is the last message. */ } } }