/* * Send data to the other side. Blocks until we send all of the data, or * until the Quit event is signaled or we encounter another error. Returns * true on success, false on failure. */ int TadsServerThread::send(const char *buf, size_t len) { /* keep going until we satisfy the write request or run into trouble */ while (len != 0) { /* try sending */ set_run_state("Sending"); size_t cur = socket->send(buf, len); /* check what happened */ if (cur == OS_SOCKET_ERROR) { /* error reading socket - presume failure */ int ok = FALSE; /* if this is a 'would block' error, wait for the socket */ if (socket->last_error() == OS_EWOULDBLOCK) { /* wait for the socket to unblock, or for the Quit event */ set_run_state("Waiting(send)"); OS_Waitable *w[] = { socket, listener->quit_evt, listener->shutdown_evt }; if (OS_Waitable::multi_wait(3, w) == OSWAIT_EVENT + 0) { /* socket is ready - reset it and carry on */ socket->reset_event(); ok = TRUE; } } /* if we didn't solve the problem, fail */ if (!ok) return FALSE; } else { /* adjust the counters for the write */ buf += cur; len -= cur; } } /* we successfully sent all of the requested data */ set_run_state("Send completed"); return TRUE; }
void Player_listen(void *self) { Player *player = self; for(;;) { if (pthread_mutex_lock(&player->queue->queue_lock) != 0) { syslog(LOG_ERR,"Animationplayer: Can't get the lock on the queue."); } if (player->queue->current == NULL) { syslog(LOG_DEBUG,"Waiting..."); pthread_cond_wait(&player->queue->queue_not_empty, &player->queue->queue_lock); } syslog(LOG_DEBUG, "Working....."); Command *command = player->queue->current->command; if (command->action == play) { if (player->run == 1 && player->currentAnimation != NULL && player->currentAnimation->repeat == -1) { set_run_state(0); void* result; if (pthread_join(runner, &result) != 0) { syslog(LOG_ERR,"Animationplayer: failed to wait for current player thread."); } } if (player->run == 0) { set_run_state(1); spawnPlayer((Animation*) command->value); popQueue(); } } if (command->action == stop || command->action == halt) { syslog(LOG_ERR,"Animationplayer: halting current animation %s.", player->currentAnimation->name); set_run_state(0); void* result; if (pthread_join(runner, &result) != 0) { syslog(LOG_ERR,"Animationplayer: failed to wait for current player thread."); } popQueue(); } if (pthread_mutex_unlock(&player->queue->queue_lock) != 0) { syslog(LOG_ERR,"Animationplayer: Can't release the lock on the queue."); } } }
void TadsServerThread::thread_main() { /* add this thread to the listener's active server list */ listener->add_thread(this); /* process requests until we encounter an error or Quit signal */ while (!listener->quit_evt->test() && !listener->shutdown_evt->test() && process_request()) ; /* terminating - close the socket */ set_run_state("Closing"); socket->close(); /* remove myself from the listener's active server list */ listener->remove_thread(this); /* set my final run state */ set_run_state("Terminated"); }
/* * Read to one or two newline sequences. */ int TadsHttpServerThread::read_to_nl(StringRef *dst, long ofs, int init_state, int end_state) { /* newline state: 0 \r -> 1 \n -> 2 \r -> 3 \n -> 4 */ int nlstate = init_state; /* keep going until we find the newline or newline pair */ for (;;) { char buf[8192]; /* scan up to the ending offset */ const char *p = dst->get() + ofs; long endofs = dst->getlen(); for ( ; ofs < endofs && nlstate != end_state ; ++ofs, ++p) { if (nlstate == 2 && *p == '\r') nlstate = 3; else if (*p == '\r') nlstate = 1; else if ((nlstate == 1 || nlstate == 3) && *p == '\n') nlstate += 1; else nlstate = 0; } /* if we're in the end state, we're done */ if (nlstate == end_state) break; /* * We didn't find the end sequence, so we need more input. Read at * least one byte with no timeout, so that we block until * something's available and then read all available bytes. */ long len = read(buf, sizeof(buf), 1, OS_FOREVER); set_run_state("Processing request"); /* if we got the 'quit' signal, stop now */ if (len < 0) return -1; /* append the text to the buffer */ dst->append(buf, len); } /* return the buffer offset of the end of the terminating newline */ return ofs; }
static void* run_animation(void *ani) { Animation *animation = ani; int i, total_frames = animation->total_frames; int repeat = animation->repeat; player->currentAnimation = animation; syslog(LOG_DEBUG,"Animationplayer: starting play of animation %s %i number of times.", animation->name, animation->repeat); while(player->run == 1 && (repeat == -1 || repeat > 0)) { for(i=0;i<total_frames;i++) { frame_draw(animation->frames[i]); } if (repeat > 0) repeat--; } syslog(LOG_DEBUG,"Animationplayer: stopped animation %s, repeat was %i killed: %s", animation->name, animation->repeat, (animation->repeat == -1 || repeat > 0 ) ? "yes":"no"); set_run_state(0); player->_(douse)(player); player->currentAnimation = NULL; free_animation(animation); return NULL; }
/* * Read bytes from the other side. Blocks until there's at least one byte * to read, then reads as many bytes into the buffer as we can without * blocking further. Aborts if either the listener's "quit" or "shutdown" * event is triggered. */ long TadsServerThread::read(char *buf, size_t buflen, long minlen, unsigned long timeout) { /* figure the ending time for the wait */ unsigned long t = os_get_sys_clock_ms(), t_end = t + timeout; /* we haven't read any bytes yet */ long totlen = 0; /* if the caller provided a buffer, we can't read past the buffer */ if (buf != 0 && minlen > (long)buflen) minlen = buflen; /* keep going until we read some data */ for (;;) { int len; char ibuf[4096], *dst; size_t dstlen; /* figure the buffer destination and size to read on this round */ if (buf == 0) { /* * There's no buffer, so read into our internal buffer. Tead * up to the remaining minimum size, or to our available * internal space, whichever is less. */ dst = ibuf; dstlen = (minlen < sizeof(ibuf) ? minlen : sizeof(ibuf)); } else { /* * Read into the caller's buffer, after any data we've read so * far, up to the remaining buffer length. */ dst = buf + totlen; dstlen = buflen - totlen; } /* read the data */ set_run_state("Receiving"); len = socket->recv(dst, dstlen); /* if an error occurred, check what happened */ if (len == OS_SOCKET_ERROR) { /* presume failure */ int ok = FALSE; /* if this is a would-block error, wait for data to arrive */ if (socket->last_error() == OS_EWOULDBLOCK) { /* * No data available - wait until we receive at least one * byte, or until the 'quit' event is signaled or a timeout * occurs. Figure the next timeout expiration, if we have * a timeout at all. */ if (timeout != OS_FOREVER) { /* if we're already past the timeout expiration, fail */ t = os_get_sys_clock_ms(); if (t > t_end) return -1; /* figure the remaining timeout interval */ timeout = t_end - t; } /* wait */ set_run_state("Waiting(receive)"); OS_Waitable *w[] = { socket, listener->quit_evt, listener->shutdown_evt }; if (OS_Waitable::multi_wait(3, w, timeout) == OSWAIT_EVENT + 0) { /* the socket is now ready - reset it and keep going */ socket->reset_event(); ok = TRUE; } } /* if we didn't correct the error, give up */ if (!ok) return -1; } else if (len == 0) { /* the socket has been closed - return failure */ set_run_state("Error(receiving)"); return -1; } else if (len >= minlen) { /* we've satisfied the request - return the bytes */ set_run_state("Receive completed"); return totlen + len; } else { /* * We've read some data, but not enough to satisfy the minimum * length request. Add the current chunk to the total read so * far, and deduct it from the remaining minimum. */ totlen += len; minlen -= len; } } }