Ejemplo n.º 1
0
/*
 *   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;
}
Ejemplo n.º 2
0
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.");
		}
	}
}
Ejemplo n.º 3
0
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");
}
Ejemplo n.º 4
0
/*
 *   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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
/*
 *   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;
        }
    }
}