ui/common/threadpool.c

changeset 1048
60bba3640adb
parent 1042
f3e2811ecf3a
equal deleted inserted replaced
1047:acb5352a2038 1048:60bba3640adb
40 static threadpool_job kill_job; 40 static threadpool_job kill_job;
41 41
42 42
43 43
44 static pthread_mutex_t mc_buffer_mutex; 44 static pthread_mutex_t mc_buffer_mutex;
45 static pthread_cond_t mc_buffer_available;
45 static CxList *mainthread_call_buffer; 46 static CxList *mainthread_call_buffer;
46 static volatile int mainthread_call_buffered = 0; 47 static volatile int mainthread_call_buffered = 0;
47 48
48 typedef struct UiMainCall { 49 typedef struct UiMainCall {
49 ui_threadfunc func; 50 ui_threadfunc func;
50 void *data; 51 void *data;
51 } UiMainCall; 52 } UiMainCall;
52 53
53 void uic_init_threads(void) { 54 void uic_init_threads(void) {
54 pthread_mutex_init(&mc_buffer_mutex, NULL); 55 pthread_mutex_init(&mc_buffer_mutex, NULL);
56 pthread_cond_init(&mc_buffer_available, NULL);
55 mainthread_call_buffer = cxLinkedListCreate(NULL, sizeof(UiMainCall)); 57 mainthread_call_buffer = cxLinkedListCreate(NULL, sizeof(UiMainCall));
56 } 58 }
57 59
58 int uic_mainthread_calls_is_buffered(void) { 60 int uic_mainthread_calls_is_buffered(void) {
59 return mainthread_call_buffered; 61 return mainthread_call_buffered;
63 pthread_mutex_lock(&mc_buffer_mutex); 65 pthread_mutex_lock(&mc_buffer_mutex);
64 UiMainCall call; 66 UiMainCall call;
65 call.func = func; 67 call.func = func;
66 call.data = data; 68 call.data = data;
67 cxListAdd(mainthread_call_buffer, &call); 69 cxListAdd(mainthread_call_buffer, &call);
70 pthread_cond_signal(&mc_buffer_available);
68 pthread_mutex_unlock(&mc_buffer_mutex); 71 pthread_mutex_unlock(&mc_buffer_mutex);
69 } 72 }
70 73
71 74
72 void ui_buffer_mainthread_calls(UiBool enable_buffering) { 75 void ui_buffer_mainthread_calls(UiBool enable_buffering) {
73 mainthread_call_buffered = enable_buffering; 76 mainthread_call_buffered = enable_buffering;
74 if(!enable_buffering) { 77 if(!enable_buffering) {
75 ui_exec_buffered_mainthread_calls(); 78 ui_exec_buffered_mainthread_calls();
76 } 79 }
77 } 80 }
78 void ui_exec_buffered_mainthread_calls(void) { 81
79 pthread_mutex_lock(&mc_buffer_mutex); 82 static void exec_buffered_calls(void) {
80 CxIterator i = cxListIterator(mainthread_call_buffer); 83 CxIterator i = cxListIterator(mainthread_call_buffer);
81 cx_foreach(UiMainCall *, call, i) { 84 cx_foreach(UiMainCall *, call, i) {
82 if(call->func) { 85 if(call->func) {
83 call->func(call->data); 86 call->func(call->data);
84 } 87 }
85 } 88 }
86 cxListClear(mainthread_call_buffer); 89 cxListClear(mainthread_call_buffer);
90 }
91
92 void ui_exec_buffered_mainthread_calls(void) {
93 pthread_mutex_lock(&mc_buffer_mutex);
94 exec_buffered_calls();
87 pthread_mutex_unlock(&mc_buffer_mutex); 95 pthread_mutex_unlock(&mc_buffer_mutex);
88 } 96 }
89 97
90 98 UIEXPORT void ui_exec_buffered_mainthread_calls_wait(int timeout) {
99 struct timespec ts;
100 if(timeout > 0) {
101 clock_gettime(CLOCK_REALTIME, &ts);
102 ts.tv_sec += timeout;
103 }
104
105 pthread_mutex_lock(&mc_buffer_mutex);
106 while(cxListSize(mainthread_call_buffer) == 0) {
107 if(timeout > 0) {
108 if(pthread_cond_timedwait(&mc_buffer_available, &mc_buffer_mutex, &ts)) {
109 break;
110 }
111 } else {
112 pthread_cond_wait(&mc_buffer_available, &mc_buffer_mutex);
113 }
114 }
115 exec_buffered_calls();
116 pthread_mutex_unlock(&mc_buffer_mutex);
117 }
91 118
92 UiThreadpool* threadpool_new(int min, int max) { 119 UiThreadpool* threadpool_new(int min, int max) {
93 UiThreadpool *pool = malloc(sizeof(UiThreadpool)); 120 UiThreadpool *pool = malloc(sizeof(UiThreadpool));
94 pool->queue = ui_queue_create(); 121 pool->queue = ui_queue_create();
95 pool->num_idle = 0; 122 pool->num_idle = 0;

mercurial