/** 在当前结点前面插入新结点,并将数据的副本记录到该结点上 */ LCUI_API void* LinkedList_InsertCopy( LinkedList *list, void *data ) { void *data_copy; data_copy = malloc( list->node_data_size ); memcpy( data_copy, data, list->node_data_size ); LinkedList_Insert( list, data_copy ); return data_copy; }
/** 运行目标主循环 */ int LCUI_MainLoop_Run( LCUI_MainLoop loop ) { if( loop->state == STATE_RUNNING ) { _DEBUG_MSG("error: main-loop already running."); return -1; } DEBUG_MSG("loop: %p, enter\n", loop); loop->state = STATE_RUNNING; /* 将主循环记录插入至列表表头 */ LinkedList_Goto( &MainApp.loop_list, 0 ); LinkedList_Insert( &MainApp.loop_list, loop ); MainApp.loop = loop; LCUIMutex_Lock( &MainApp.loop_changed ); /* 广播,让其它线程交出主循环运行权 */ LCUICond_Broadcast( &MainApp.loop_cond ); /* 获取运行权 */ LCUIMutex_Lock( &MainApp.loop_mutex ); LCUIMutex_Unlock( &MainApp.loop_changed ); loop->tid = LCUIThread_SelfID(); while( loop->state != STATE_EXITED ) { if( LinkedList_GetTotal(&MainApp.task_list) <= 0 ) { DEBUG_MSG("loop: %p, sleeping...\n", loop); LCUICond_TimedWait( &MainApp.loop_cond, 1000 ); DEBUG_MSG("loop: %p, wakeup\n", loop); /** 如果当前运行的主循环不是自己 */ if( MainApp.loop != loop ) { loop->state = STATE_PAUSED; DEBUG_MSG("loop: %p, release control.\n", loop); LCUIMutex_Unlock( &MainApp.loop_mutex ); /* 等待其它线程获得主循环运行权 */ LCUIMutex_Lock( &MainApp.loop_changed ); LCUIMutex_Unlock( &MainApp.loop_changed ); DEBUG_MSG("loop: %p, waiting...\n", loop); /* 等待其它线程释放主循环运行权 */ LCUIMutex_Lock( &MainApp.loop_mutex ); } continue; } DEBUG_MSG("loop: %p, run task.\n", loop); LCUI_RunTask(); } loop->state = STATE_EXITED; LinkedList_Goto( &MainApp.loop_list, 0 ); LinkedList_Delete( &MainApp.loop_list ); /* 获取处于列表表头的主循环 */ loop = (LCUI_MainLoop)LinkedList_Get( &MainApp.loop_list ); if( loop ) { /* 改变当前运行的主循环 */ MainApp.loop = loop; LCUICond_Broadcast( &MainApp.loop_cond ); } /* 释放运行权 */ LCUIMutex_Unlock( &MainApp.loop_mutex ); /* 如果列表为空,一般意味着LCUI需要退出了 */ if( LinkedList_GetTotal( &MainApp.loop_list ) <= 0 ) { /** 广播,通知相关线程开始进行清理操作 */ LCUICond_Broadcast( &MainApp.loop_list_empty ); } DEBUG_MSG("loop: %p, exit\n", loop); return 0; }