Exemplo n.º 1
0
loop_t* loop_new(unsigned hint)
{
    loop_t* loop;
    int epfd;

    (void)current_tid();

    loop = (loop_t*)malloc(sizeof(loop_t));
    memset(loop, 0, sizeof(*loop));
    loop->run = 0;
    
    if (hint < 64)
    {
        hint = 64;
    }

    epfd = epoll_create(hint);
    if (epfd < 0)
    {
        free(loop);
        log_error("loop_new: epoll_create() failed, error: %d", errno);
        return NULL;
    }

    loop->epfd = epfd;

    loop->max_event_count = hint;
    loop->events = (struct epoll_event*)malloc(sizeof(struct epoll_event) * hint);
    memset(loop->events, 0, (sizeof(struct epoll_event) * hint));

    loop->task_queue = async_task_queue_create(loop);
    loop->timer_queue = timer_queue_create(loop);

    return loop;
}
Exemplo n.º 2
0
int loop_inloopthread(loop_t* loop)
{
    if (NULL == loop)
    {
        return 0;
    }
    
    return (loop->threadId == current_tid()) ? 1 : 0;
}
Exemplo n.º 3
0
void loop_run_inloop(loop_t* loop, void(*callback)(void *userdata), void* userdata)
{
    if (NULL == loop || NULL == callback)
    {
        return;
    }

    if ((loop->run == 0) || (loop->threadId == current_tid()))
    {
        callback(userdata);
    }
    else
    {
        async_task_queue_submit(loop->task_queue, callback, userdata);
    }

    return;
}
Exemplo n.º 4
0
void loop_loop(loop_t *loop)
{
    int result;
    int i;
    long timeout;
    struct epoll_event *event;
    channel_t* channel;
    int error;
    
    struct rlimit limit;

    if (NULL == loop)
    {
        return;
    }

    loop->threadId = current_tid();
    loop->run = 1;

    while (loop->run != 0)
    {
        timeout = timer_queue_gettimeout(loop->timer_queue);
        memset(loop->events, 0, loop->max_event_count * sizeof(struct epoll_event));
        result = epoll_wait(loop->epfd, loop->events, loop->max_event_count, timeout);
        error = errno;

        if (result > 0)
        {
            for (i = 0; i < result; ++i)
            {
                event = &(loop->events[i]);
                channel = (channel_t*)event->data.ptr;
                channel_setrevent(channel, event->events);
            }
            for (i = 0; i < result; ++i)
            {
                event = &(loop->events[i]);
                channel = (channel_t*)event->data.ptr;
                channel_onevent(channel);
            }

            if (result == loop->max_event_count)
            {
                memset(&limit, 0, sizeof(limit));
                getrlimit(RLIMIT_NOFILE, &limit);

                if (result < limit.rlim_cur)
                {
                    result *= 2;
                    if (result > limit.rlim_cur)
                    {
                        result = limit.rlim_cur;
                    }

                    loop->events = realloc(loop->events, result*sizeof(struct epoll_event));
                    loop->max_event_count = result;
                }
            }
        }
        else if (0 > result && EINTR != error)
        {
            log_error("loop_loop: epoll_wait() failed, errno: %d", error);
        }

        timer_queue_process_inloop(loop->timer_queue);
    }

    return;
}
Exemplo n.º 5
0
int begin_wait_thread( int pid, int tid, int *rc )
{
  int success = -1;
  int size;
  struct wait_info *nw 	= NULL;
  struct process *proc;
  struct thread *tr;

  ASSERT( pid == current_pid() );
  
  proc = checkout_process( pid, WRITER );
  ASSERT( proc != NULL );

  	tr = find_thread_with_id( proc, tid );
	if ( tr == NULL )
	{
		commit_process( proc );
		return -1;
	}


	// --------------------------------
	
	size = sizeof(struct wait_info);
	nw = (struct wait_info*)malloc( size ); 
	
	  nw->next = NULL;
	  nw->prev = NULL;
	  
		  nw->pid 		= current_pid();
		  nw->tid	 	= current_tid();
		  nw->success 	= -1;	// Assume failure from the very beginning.
		  nw->rc 		= -1;

	current_thread()->active_wait = nw;	// Set our active wait information.
		  
	// Now we insert it into the wait list.
	  if ( tr->waits != NULL ) tr->waits->prev = nw;
	  nw->next = tr->waits;
	  tr->waits = nw;

	// -----------------------------
	commit_process( proc );

	// ------  Now we go to sleep -------------
		proc = checkout_process( current_pid(), WRITER );
		if ( proc == NULL )
		{
			/// \todo freak out and handle stuff properly
			return -1;
		}
	
		   	disable_interrupts();
			   atomic_dec( &(proc->kernel_threads) );
			   set_thread_state( current_thread(), THREAD_WAITING );  
			   commit_process( proc );
			enable_interrupts();
			
			sched_yield();		// Release!	
			
						// Secure ourselves.
			atomic_inc( &(proc->kernel_threads) );

	// Get our process back.
  	proc = checkout_process( current_pid(), WRITER );
	if ( proc == NULL ) return -1;
			
		current_thread()->active_wait = NULL;

	commit_process( proc );
	
		// We're back. Return the correct info.
		 *rc = nw->rc;
		 success = nw->success;
	
		 // nw should have been unlinked by the scheduler.
		 // waiter should have active_wait cleared by the
		 // scheduler as well.
		 // we just need to delete it.
	
		free( nw );

  return success;

}
Exemplo n.º 6
0
int begin_wait_process( int pid, int *rc )
{
  int success = -1;
  struct wait_info *nw 	= NULL;
  struct process *proc;

  proc = checkout_process( pid, WRITER );
  if ( proc == NULL ) return -1;


	nw = (struct wait_info*)malloc( sizeof(struct wait_info) ); 
	
	  nw->next = NULL;
	  nw->prev = NULL;
	  
		  nw->pid 		= current_pid();
		  nw->tid	 	= current_tid();
		  nw->success 	= -1;	// Assume failure from the very beginning.
		  nw->rc 		= -1;

	// Now we insert it into the wait list.
	  if ( proc->waits != NULL ) proc->waits->prev = nw;
	  nw->next = proc->waits;
	  proc->waits = nw;

	// -----------------------------
	commit_process( proc );

	// ------  Now we go to sleep -------------
		proc = checkout_process( current_pid(), WRITER );
		ASSERT( proc != NULL );

		current_thread()->active_wait = nw;		// Save our active wait.
	
		   	disable_interrupts();
			   atomic_dec( &(proc->kernel_threads) );
			   set_thread_state( current_thread(), THREAD_WAITING );  
			   commit_process( proc );
			enable_interrupts();

			sched_yield();	
			
			atomic_inc( &(proc->kernel_threads) );	// Secure this thread.
		
	// Get our process back.
  	proc = checkout_process( current_pid(), WRITER );
	ASSERT( proc != NULL );

		current_thread()->active_wait = NULL;
	
	commit_process( proc );

			
	// We're back. Return the correct info.
	 *rc = nw->rc;
	 success = nw->success;

	 // nw should have been unlinked by the scheduler.
	 // waiter should have active_wait cleared by the
	 // scheduler as well.
	 // we just need to delete it.

	free( nw );

	/// \todo active_waits for threads.

  return success;
}