| 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; |