예제 #1
0
static void iothread_instance_finalize(Object *obj)
{
    IOThread *iothread = IOTHREAD(obj);

    iothread_stop(iothread);
    /*
     * Before glib2 2.33.10, there is a glib2 bug that GSource context
     * pointer may not be cleared even if the context has already been
     * destroyed (while it should).  Here let's free the AIO context
     * earlier to bypass that glib bug.
     *
     * We can remove this comment after the minimum supported glib2
     * version boosts to 2.33.10.  Before that, let's free the
     * GSources first before destroying any GMainContext.
     */
    if (iothread->ctx) {
        aio_context_unref(iothread->ctx);
        iothread->ctx = NULL;
    }
    if (iothread->worker_context) {
        g_main_context_unref(iothread->worker_context);
        iothread->worker_context = NULL;
    }
    qemu_cond_destroy(&iothread->init_done_cond);
    qemu_mutex_destroy(&iothread->init_done_lock);
}
예제 #2
0
int32_t iothread_start( struct iothread * self, uint8_t index, iothreads_t parent )
{
    self->index = index;
    self->parent = parent;

    self->sets = evsets_create();
    if ( self->sets == NULL )
    {
        iothread_stop(self);
        return -1;
    }

    self->cmdevent = event_create();
    self->queue = msgqueue_create( MSGQUEUE_DEFAULT_SIZE );
    if ( self->queue == NULL || self->cmdevent == NULL )
    {
        iothread_stop(self);
        return -2;
    }

    // 初始化命令事件
    event_set( self->cmdevent, msgqueue_popfd(self->queue), EV_READ|EV_PERSIST );
    event_set_callback( self->cmdevent, iothread_on_command, self );
    evsets_add( self->sets, self->cmdevent, 0 );

    // 启动线程
    pthread_attr_t attr;
    pthread_attr_init( &attr );
    //    assert( pthread_attr_setstacksize( &attr, THREAD_DEFAULT_STACK_SIZE ) );
    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );

    int32_t rc = pthread_create(&(self->id), &attr, iothread_main, self);
    pthread_attr_destroy( &attr );

    if ( rc != 0 )
    {
        iothread_stop(self);
        return -3;
    }

    return 0;
}
예제 #3
0
파일: iothread.c 프로젝트: pfliu/qemu
static int iothread_stop_iter(Object *object, void *opaque)
{
    IOThread *iothread;

    iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
    if (!iothread) {
        return 0;
    }
    iothread_stop(iothread);
    return 0;
}
예제 #4
0
파일: iothread.c 프로젝트: EternalKeel/qemu
static void iothread_instance_finalize(Object *obj)
{
    IOThread *iothread = IOTHREAD(obj);

    iothread_stop(obj, NULL);
    qemu_cond_destroy(&iothread->init_done_cond);
    qemu_mutex_destroy(&iothread->init_done_lock);
    if (!iothread->ctx) {
        return;
    }
    aio_context_unref(iothread->ctx);
}
예제 #5
0
void iothreads_stop( iothreads_t self )
{
	uint8_t i = 0;
	struct iothreads * iothreads = (struct iothreads *)(self);

	// 向所有线程发送停止命令
	iothreads->runflags = 0;
	for ( i = 0; i < iothreads->nthreads; ++i )
	{
		iothread_post( iothreads->threadgroup+i, eTaskType_Null, 0, NULL, 0 );
	}

	// 等待线程退出
	pthread_mutex_lock( &iothreads->lock );
	while ( iothreads->nrunthreads > 0 )
	{
		pthread_cond_wait( &iothreads->cond, &iothreads->lock );
	}
	pthread_mutex_unlock( &iothreads->lock );

	// 销毁所有网络线程
	for ( i = 0; i < iothreads->nthreads; ++i )
	{
		iothread_stop( iothreads->threadgroup + i );
	}
	
	pthread_cond_destroy( &iothreads->cond );
	pthread_mutex_destroy( &iothreads->lock );
	if ( iothreads->threadgroup )
	{
		free( iothreads->threadgroup );
		iothreads->threadgroup = NULL;
	}

	free ( iothreads );

	return;
}