/* * Write the bytes in the buffer to the socket. * Takes a connection and returns the number of bytes written. */ ssize_t write_buffer(int fd, struct buffer_s * buffptr) { ssize_t bytessent; struct bufline_s *line; assert(fd >= 0); assert(buffptr != NULL); if (buffptr->size == 0) return 0; /* Sanity check. It would be bad to be using a NULL pointer! */ assert(BUFFER_HEAD(buffptr) != NULL); line = BUFFER_HEAD(buffptr); bytessent = send(fd, line->string + line->pos, line->length - line->pos, MSG_NOSIGNAL); if (bytessent >= 0) { /* bytes sent, adjust buffer */ line->pos += bytessent; if (line->pos == line->length) free_line(remove_from_buffer(buffptr)); return bytessent; } else { switch (errno) { #ifdef EWOULDBLOCK case EWOULDBLOCK: #else # ifdef EAGAIN case EAGAIN: # endif #endif case EINTR: return 0; case ENOBUFS: case ENOMEM: log_message(LOG_ERR, "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d", strerror(errno), fd); return 0; default: log_message(LOG_ERR, "writebuff: write() error \"%s\" on file descriptor %d", strerror(errno), fd); return -1; } } }
static void sensorServer() { char com1Name[] = IOSERVERCOM1_NAME; int com1 = WhoIs(com1Name); char sensorName[] = SENSOR_NAME; RegisterAs(sensorName); int i, j; CURR_SENSOR_BOX = 0; CURR_HIGH_BITS = 0; responseIndex = 0; for (i = 0; i < NUM_SENSOR_BOX; ++i) { for (j = 0; j < 16; ++j) { SENSOR_VALUE[i][j] = 0; } } subscriberIndex = 0; subscriberUpdateIndex = 0; sensorBufferHead = 0; sensorBufferTail = 0; int queryWorker = Create(7, sensorQueryWorker); Create(8, sensorQueryResponseWorker); int queryTimeoutWorker = Create(7, sensorQueryTimeoutWorker); int queryResponseTimeoutWorker = Create(7, sensorQueryResponseTimeoutWorker); int courier = Create(7, sensorCourier); int queryWorkerReady = 0; int queryTimeout = 0; int queryResponseTimeout = 0; int startQueryResponseTimeout = 0; int courierReady = 0; char timerName[] = TIMESERVER_NAME; int timer = WhoIs(timerName); IGNORE_RESULT = 1; // sensor server is time sensitive, it delays and tries // to avoid the initialization period where there are // a lot of chars in com1 buffer Delay(700, timer); // Clear sensor memory after reading. Putc(com1, 192); // end init for ( ;; ) { if (queryTimeout && queryWorkerReady) { queryTimeout = 0; queryWorkerReady = 0; Reply(queryWorker, (char *)NULL, 0); Reply(queryTimeoutWorker, (char *)NULL, 0); } int tid = -1; SensorMsg msg; Receive(&tid, (char*)&msg, sizeof(SensorMsg)); switch (msg.type) { case QUERY_WORKER: { queryWorkerReady = 1; break; } case QUERY_RESPONSE_WORKER: { Reply(tid, (char *)NULL, 0); char response = msg.data; if (responseIndex == 0) { if (queryResponseTimeout) { queryResponseTimeout = 0; Reply(queryResponseTimeoutWorker, (char *)NULL, 0); } else { startQueryResponseTimeout = 1; } } responseBuffer[responseIndex++] = response; if (responseIndex == 10) { for (int i = 0; i < 10; i++) { sensorResponded(responseBuffer[i], msg.time); } responseIndex = 0; } break; } case QUERY_TIMEOUT_WORKER: { queryTimeout = 1; break; } case QUERY_RESPONSE_TIMEOUT_WORKER: { if (startQueryResponseTimeout) { startQueryResponseTimeout = 0; Reply(queryResponseTimeoutWorker, (char *)NULL, 0); } else { queryResponseTimeout = 1; responseIndex = 0; CURR_SENSOR_BOX = 0; CURR_HIGH_BITS = 0; } break; } case QUERY_RECENT: { sensorSubscriber[subscriberIndex++] = tid; Reply(tid, (char *)NULL, 0); break; } case SENSOR_COURIER: { courierReady = 1; break; } case FAKE_TRIGGER: { Reply(tid, (char *)NULL, 0); Sensor s; s.box = msg.box; s.val = msg.data; s.time = msg.time; add_to_buffer(s); break; } default: { ASSERT(FALSE, "invalid sensor msg type."); } } if (courierReady && !buffer_empty() && subscriberIndex != 0) { Sensor s = sensorBuffer[sensorBufferTail]; SensorWorkUnit work; work.sensor = s; work.tid = sensorSubscriber[subscriberUpdateIndex++]; Reply(courier, (char *)&work, sizeof(SensorWorkUnit)); if (subscriberUpdateIndex == subscriberIndex) { subscriberUpdateIndex = 0; remove_from_buffer(); } } } }