aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/luaproc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/luaproc/luaproc.c72
-rw-r--r--libraries/luaproc/luaproc.h5
-rw-r--r--libraries/luaproc/sched.c44
3 files changed, 98 insertions, 23 deletions
diff --git a/libraries/luaproc/luaproc.c b/libraries/luaproc/luaproc.c
index 2ec5b31..ff18723 100644
--- a/libraries/luaproc/luaproc.c
+++ b/libraries/luaproc/luaproc.c
@@ -114,6 +114,7 @@ static const struct luaL_reg luaproc_funcs_child[] = {
114 { NULL, NULL } 114 { NULL, NULL }
115}; 115};
116 116
117/*
117static void registerlib( lua_State *L, const char *name, lua_CFunction f ) { 118static void registerlib( lua_State *L, const char *name, lua_CFunction f ) {
118 lua_getglobal( L, "package" ); 119 lua_getglobal( L, "package" );
119 lua_getfield( L, -1, "preload" ); 120 lua_getfield( L, -1, "preload" );
@@ -121,8 +122,9 @@ static void registerlib( lua_State *L, const char *name, lua_CFunction f ) {
121 lua_setfield( L, -2, name ); 122 lua_setfield( L, -2, name );
122 lua_pop( L, 2 ); 123 lua_pop( L, 2 );
123} 124}
124 125*/
125static void openlibs( lua_State *L ) { 126static void openlibs( lua_State *L ) {
127/*
126 lua_cpcall( L, luaopen_base, NULL ); 128 lua_cpcall( L, luaopen_base, NULL );
127 lua_cpcall( L, luaopen_package, NULL ); 129 lua_cpcall( L, luaopen_package, NULL );
128 registerlib( L, "io", luaopen_io ); 130 registerlib( L, "io", luaopen_io );
@@ -131,6 +133,8 @@ static void openlibs( lua_State *L ) {
131 registerlib( L, "string", luaopen_string ); 133 registerlib( L, "string", luaopen_string );
132 registerlib( L, "math", luaopen_math ); 134 registerlib( L, "math", luaopen_math );
133 registerlib( L, "debug", luaopen_debug ); 135 registerlib( L, "debug", luaopen_debug );
136*/
137 luaL_openlibs(L);
134} 138}
135 139
136/* return status (boolean) indicating if lua process should be recycled */ 140/* return status (boolean) indicating if lua process should be recycled */
@@ -195,7 +199,7 @@ int luaproc_recycle_push( luaproc lp ) {
195} 199}
196 200
197/* create new luaproc */ 201/* create new luaproc */
198luaproc luaproc_new( const char *code, int destroyflag ) { 202static luaproc luaproc_new( const char *code, int destroyflag, int file) {
199 203
200 luaproc lp; 204 luaproc lp;
201 int ret; 205 int ret;
@@ -218,7 +222,10 @@ luaproc luaproc_new( const char *code, int destroyflag ) {
218 luaL_register( lpst, "luaproc", luaproc_funcs_child ); 222 luaL_register( lpst, "luaproc", luaproc_funcs_child );
219 223
220 /* load process' code */ 224 /* load process' code */
221 ret = luaL_loadstring( lpst, code ); 225 if (file)
226 ret = luaL_loadfile( lpst, code );
227 else
228 ret = luaL_loadstring( lpst, code );
222 /* in case of errors, destroy recently created lua process */ 229 /* in case of errors, destroy recently created lua process */
223 if ( ret != 0 ) { 230 if ( ret != 0 ) {
224 lua_close( lpst ); 231 lua_close( lpst );
@@ -231,7 +238,7 @@ luaproc luaproc_new( const char *code, int destroyflag ) {
231 238
232/* synchronize worker threads and exit */ 239/* synchronize worker threads and exit */
233static int luaproc_exit( lua_State *L ) { 240static int luaproc_exit( lua_State *L ) {
234 sched_join_workerthreads( ); 241 sched_join_workerthreads();
235 return 0; 242 return 0;
236} 243}
237 244
@@ -297,7 +304,7 @@ static int luaproc_destroy_worker( lua_State *L ) {
297 304
298 /* create new lua process with empty code and destroy worker flag set to true 305 /* create new lua process with empty code and destroy worker flag set to true
299 (ie, conclusion of lua process WILL result in worker thread destruction */ 306 (ie, conclusion of lua process WILL result in worker thread destruction */
300 lp = luaproc_new( "", TRUE ); 307 lp = luaproc_new( "", TRUE, FALSE );
301 308
302 /* ensure process creation was successfull */ 309 /* ensure process creation was successfull */
303 if ( lp == NULL ) { 310 if ( lp == NULL ) {
@@ -328,7 +335,7 @@ static int luaproc_destroy_worker( lua_State *L ) {
328} 335}
329 336
330/* recycle a lua process */ 337/* recycle a lua process */
331luaproc luaproc_recycle( luaproc lp, const char *code ) { 338static luaproc luaproc_recycle( luaproc lp, const char *code, int file ) {
332 339
333 int ret; 340 int ret;
334 341
@@ -351,12 +358,9 @@ luaproc luaproc_recycle( luaproc lp, const char *code ) {
351 return lp; 358 return lp;
352} 359}
353 360
354/* create and schedule a new lua process (luaproc.newproc) */
355static int luaproc_create_newproc( lua_State *L ) {
356
357 /* check if first argument is a string (lua code) */
358 const char *code = luaL_checkstring( L, 1 );
359 361
362int newProc(const char *code, int file)
363{
360 /* new lua process pointer */ 364 /* new lua process pointer */
361 luaproc lp; 365 luaproc lp;
362 366
@@ -365,21 +369,18 @@ static int luaproc_create_newproc( lua_State *L ) {
365 369
366 /* if there is a lua process available on the recycle queue, recycle it */ 370 /* if there is a lua process available on the recycle queue, recycle it */
367 if ( lp != NULL ) { 371 if ( lp != NULL ) {
368 lp = luaproc_recycle( lp, code ); 372 lp = luaproc_recycle( lp, code, file );
369 } 373 }
370 /* otherwise create a new one from scratch */ 374 /* otherwise create a new one from scratch */
371 else { 375 else {
372 /* create new lua process with destroy worker flag set to false 376 /* create new lua process with destroy worker flag set to false
373 (ie, conclusion of lua process will NOT result in worker thread destruction */ 377 (ie, conclusion of lua process will NOT result in worker thread destruction */
374 lp = luaproc_new( code, FALSE ); 378 lp = luaproc_new( code, FALSE, file );
375 } 379 }
376 380
377 /* ensure process creation was successfull */ 381 /* ensure process creation was successfull */
378 if ( lp == NULL ) { 382 if ( lp == NULL ) {
379 /* in case of errors return nil + error msg */ 383 return 1;
380 lua_pushnil( L );
381 lua_pushstring( L, "error loading code string" );
382 return 2;
383 } 384 }
384 385
385 /* increase active luaproc count */ 386 /* increase active luaproc count */
@@ -392,6 +393,26 @@ static int luaproc_create_newproc( lua_State *L ) {
392 sched_lpcount_dec(); 393 sched_lpcount_dec();
393 /* close lua_State */ 394 /* close lua_State */
394 lua_close( lp->lstate ); 395 lua_close( lp->lstate );
396 return 2;
397 }
398
399 return 0;
400}
401
402/* create and schedule a new lua process (luaproc.newproc) */
403static int luaproc_create_newproc( lua_State *L ) {
404
405 /* check if first argument is a string (lua code) */
406 const char *code = luaL_checkstring( L, 1 );
407
408 switch (newProc(code, FALSE))
409 {
410 case 1 :
411 /* in case of errors return nil + error msg */
412 lua_pushnil( L );
413 lua_pushstring( L, "error loading code string" );
414 return 2;
415 case 2 :
395 /* return nil + error msg */ 416 /* return nil + error msg */
396 lua_pushnil( L ); 417 lua_pushnil( L );
397 lua_pushstring( L, "error queuing process" ); 418 lua_pushstring( L, "error queuing process" );
@@ -635,17 +656,24 @@ static int luaproc_receive( lua_State *L ) {
635 } 656 }
636} 657}
637 658
638LUALIB_API int luaopen_luaproc( lua_State *L ) { 659void luaprocInit(void)
639 660{
640 /* register luaproc functions */
641 luaL_register( L, "luaproc", luaproc_funcs_parent );
642
643 /* initialize recycle list */ 661 /* initialize recycle list */
644 recyclelp = list_new(); 662 recyclelp = list_new();
645 663
646 /* initialize local scheduler */ 664 /* initialize local scheduler */
647 sched_init_local( LUAPROC_SCHED_DEFAULT_WORKER_THREADS ); 665 sched_init_local( LUAPROC_SCHED_DEFAULT_WORKER_THREADS );
666}
648 667
668void luaprocRegister(lua_State *L)
669{
670 /* register luaproc functions */
671 luaL_register( L, "luaproc", luaproc_funcs_parent );
672}
673
674LUALIB_API int luaopen_luaproc( lua_State *L ) {
675 luaprocRegister(L);
676 luaprocInit();
649 return 0; 677 return 0;
650} 678}
651 679
diff --git a/libraries/luaproc/luaproc.h b/libraries/luaproc/luaproc.h
index 86617a9..4c71685 100644
--- a/libraries/luaproc/luaproc.h
+++ b/libraries/luaproc/luaproc.h
@@ -44,6 +44,11 @@ THE SOFTWARE.
44/* lua process pointer type */ 44/* lua process pointer type */
45typedef struct stluaproc *luaproc; 45typedef struct stluaproc *luaproc;
46 46
47void luaprocInit(void);
48void luaprocRegister(lua_State *L);
49int newProc(const char *code, int file);
50
51
47/* return a process' status */ 52/* return a process' status */
48int luaproc_get_status( luaproc lp ); 53int luaproc_get_status( luaproc lp );
49 54
diff --git a/libraries/luaproc/sched.c b/libraries/luaproc/sched.c
index f19beeb..474c82b 100644
--- a/libraries/luaproc/sched.c
+++ b/libraries/luaproc/sched.c
@@ -83,9 +83,11 @@ void *workermain( void *args ) {
83 /* detach thread so resources are freed as soon as thread exits (no further joining) */ 83 /* detach thread so resources are freed as soon as thread exits (no further joining) */
84 pthread_detach( pthread_self( )); 84 pthread_detach( pthread_self( ));
85 85
86//printf("NEW WORKER\n");
86 /* main worker loop */ 87 /* main worker loop */
87 while ( 1 ) { 88 while ( 1 ) {
88 89
90//printf("a\n");
89 /* get exclusive access to the ready process queue */ 91 /* get exclusive access to the ready process queue */
90 pthread_mutex_lock( &mutex_queue_access ); 92 pthread_mutex_lock( &mutex_queue_access );
91 93
@@ -94,62 +96,83 @@ void *workermain( void *args ) {
94 pthread_cond_wait( &cond_wakeup_worker, &mutex_queue_access ); 96 pthread_cond_wait( &cond_wakeup_worker, &mutex_queue_access );
95 } 97 }
96 98
99////printf("b\n");
97 /* pop the first node from the ready process queue */ 100 /* pop the first node from the ready process queue */
98 n = list_pop_head( lpready ); 101 n = list_pop_head( lpready );
99 102
103////printf("c\n");
100 /* ensure list pop succeeded before proceeding */ 104 /* ensure list pop succeeded before proceeding */
101 if ( n != NULL ) { 105 if ( n != NULL ) {
106//printf("c.0\n");
102 /* get the popped node's data content (ie, the lua process struct) */ 107 /* get the popped node's data content (ie, the lua process struct) */
103 lp = (luaproc )list_data( n ); 108 lp = (luaproc )list_data( n );
104 } 109 }
105 else { 110 else {
111////printf("c.1\n");
106 /* free access to the process ready queue */ 112 /* free access to the process ready queue */
107 pthread_mutex_unlock( &mutex_queue_access ); 113 pthread_mutex_unlock( &mutex_queue_access );
108 /* finished thread */ 114 /* finished thread */
115//printf("c.2 pthread_exit\n");
109 pthread_exit( NULL ); 116 pthread_exit( NULL );
117//printf("c.3\n");
110 } 118 }
111 119
120////printf("d\n");
112 /* free access to the process ready queue */ 121 /* free access to the process ready queue */
113 pthread_mutex_unlock( &mutex_queue_access ); 122 pthread_mutex_unlock( &mutex_queue_access );
114 123
124//printf("e lua_resum\n");
115 /* execute the lua code specified in the lua process struct */ 125 /* execute the lua code specified in the lua process struct */
116 procstat = lua_resume( luaproc_get_state( lp ), luaproc_get_args( lp )); 126 procstat = lua_resume( luaproc_get_state( lp ), luaproc_get_args( lp ));
117 127
128//printf("f\n");
118 /* reset the process argument count */ 129 /* reset the process argument count */
119 luaproc_set_args( lp, 0 ); 130 luaproc_set_args( lp, 0 );
120 131
132////printf("g\n");
121 /* check if process finished its whole execution */ 133 /* check if process finished its whole execution */
122 if ( procstat == 0 ) { 134 if ( procstat == 0 ) {
123 135
136//printf("g.0\n");
124 /* destroy the corresponding list node */ 137 /* destroy the corresponding list node */
125 list_destroy_node( n ); 138 list_destroy_node( n );
126 139
140////printf("g.1\n");
127 /* check if worker thread should be destroyed */ 141 /* check if worker thread should be destroyed */
128 destroyworker = luaproc_get_destroyworker( lp ); 142 destroyworker = luaproc_get_destroyworker( lp );
129 143
144////printf("g.2 proc finished\n");
130 /* set process status to finished */ 145 /* set process status to finished */
131 luaproc_set_status( lp, LUAPROC_STAT_FINISHED ); 146 luaproc_set_status( lp, LUAPROC_STAT_FINISHED );
132 147
148////printf("g.3\n");
133 /* check if lua process should be recycled and, if not, destroy it */ 149 /* check if lua process should be recycled and, if not, destroy it */
134 if ( luaproc_recycle_push( lp ) == FALSE ) { 150 if ( luaproc_recycle_push( lp ) == FALSE ) {
151//printf("g.3.0 lua_close\n");
135 lua_close( luaproc_get_state( lp )); 152 lua_close( luaproc_get_state( lp ));
136 } 153 }
137 154
155////printf("g.4\n");
138 /* decrease active lua process count */ 156 /* decrease active lua process count */
139 sched_lpcount_dec(); 157 sched_lpcount_dec();
140 158
159////printf("g.5\n");
141 /* check if thread should be finished after lua process conclusion */ 160 /* check if thread should be finished after lua process conclusion */
142 if ( destroyworker ) { 161 if ( destroyworker ) {
162//printf("g.5.0 pthread_exit\n");
143 /* if so, finish thread */ 163 /* if so, finish thread */
144 pthread_exit( NULL ); 164 pthread_exit( NULL );
145 } 165 }
166//printf("g.6\n");
146 } 167 }
147 168
148 /* check if process yielded */ 169 /* check if process yielded */
149 else if ( procstat == LUA_YIELD ) { 170 else if ( procstat == LUA_YIELD ) {
150 171
172//printf("??????????????h.0\n");
151 /* if so, further check if yield originated from an unmatched send/recv operation */ 173 /* if so, further check if yield originated from an unmatched send/recv operation */
152 if ( luaproc_get_status( lp ) == LUAPROC_STAT_BLOCKED_SEND ) { 174 if ( luaproc_get_status( lp ) == LUAPROC_STAT_BLOCKED_SEND ) {
175//printf("??????????????h.1\n");
153 /* queue blocked lua process on corresponding channel */ 176 /* queue blocked lua process on corresponding channel */
154 luaproc_queue_sender( lp ); 177 luaproc_queue_sender( lp );
155 /* unlock channel access */ 178 /* unlock channel access */
@@ -159,6 +182,7 @@ void *workermain( void *args ) {
159 } 182 }
160 183
161 else if ( luaproc_get_status( lp ) == LUAPROC_STAT_BLOCKED_RECV ) { 184 else if ( luaproc_get_status( lp ) == LUAPROC_STAT_BLOCKED_RECV ) {
185//printf("??????????????h.2\n");
162 /* queue blocked lua process on corresponding channel */ 186 /* queue blocked lua process on corresponding channel */
163 luaproc_queue_receiver( lp ); 187 luaproc_queue_receiver( lp );
164 /* unlock channel access */ 188 /* unlock channel access */
@@ -169,6 +193,7 @@ void *workermain( void *args ) {
169 193
170 /* or if yield resulted from an explicit call to coroutine.yield in the lua code being executed */ 194 /* or if yield resulted from an explicit call to coroutine.yield in the lua code being executed */
171 else { 195 else {
196//printf("??????????????h.3\n");
172 /* get exclusive access to the ready process queue */ 197 /* get exclusive access to the ready process queue */
173 pthread_mutex_lock( &mutex_queue_access ); 198 pthread_mutex_lock( &mutex_queue_access );
174 /* re-insert the job at the end of the ready process queue */ 199 /* re-insert the job at the end of the ready process queue */
@@ -180,6 +205,7 @@ void *workermain( void *args ) {
180 205
181 /* check if there was any execution error (LUA_ERRRUN, LUA_ERRSYNTAX, LUA_ERRMEM or LUA_ERRERR) */ 206 /* check if there was any execution error (LUA_ERRRUN, LUA_ERRSYNTAX, LUA_ERRMEM or LUA_ERRERR) */
182 else { 207 else {
208//printf("??????????????i.0\n");
183 /* destroy the corresponding node */ 209 /* destroy the corresponding node */
184 list_destroy_node( n ); 210 list_destroy_node( n );
185 /* print error message */ 211 /* print error message */
@@ -189,6 +215,7 @@ void *workermain( void *args ) {
189 /* decrease active lua process count */ 215 /* decrease active lua process count */
190 sched_lpcount_dec(); 216 sched_lpcount_dec();
191 } 217 }
218//printf("END\n");
192 } 219 }
193} 220}
194 221
@@ -260,29 +287,42 @@ int sched_queue_proc( luaproc lp ) {
260/* synchronize worker threads */ 287/* synchronize worker threads */
261void sched_join_workerthreads( void ) { 288void sched_join_workerthreads( void ) {
262 289
290////printf(" 0\n");
263 pthread_mutex_lock( &mutex_lp_count ); 291 pthread_mutex_lock( &mutex_lp_count );
264 292
293//printf(" 1 wait for procs to end\n");
265 /* wait until there is no more active lua processes */ 294 /* wait until there is no more active lua processes */
266 while( lpcount != 0 ) { 295 while( lpcount != 0 ) {
296//printf(" 1.0\n");
267 pthread_cond_wait( &cond_no_active_lp, &mutex_lp_count ); 297 pthread_cond_wait( &cond_no_active_lp, &mutex_lp_count );
268 } 298 }
269 /* get exclusive access to the ready process queue */ 299 /* get exclusive access to the ready process queue */
300////printf(" 2\n");
270 pthread_mutex_lock( &mutex_queue_access ); 301 pthread_mutex_lock( &mutex_queue_access );
271 /* set the no more active lua processes flag to true */ 302 /* set the no more active lua processes flag to true */
303////printf(" 3\n");
272 no_more_processes = TRUE; 304 no_more_processes = TRUE;
273 /* wake ALL workers up */ 305 /* wake ALL workers up */
306//printf(" 4 wake up all workers.\n");
274 pthread_cond_broadcast( &cond_wakeup_worker ); 307 pthread_cond_broadcast( &cond_wakeup_worker );
275 /* free access to the process ready queue */ 308 /* free access to the process ready queue */
309////printf(" 5\n");
276 pthread_mutex_unlock( &mutex_queue_access ); 310 pthread_mutex_unlock( &mutex_queue_access );
311
312// We don't need this, as we only get here during shutdown. Linking this to EFL results in a hang otherwise anyway.
277 /* wait for (join) worker threads */ 313 /* wait for (join) worker threads */
278 pthread_exit( NULL ); 314//printf(" 6 pthread_exit, waiting for workers to end\n");
315// pthread_exit( NULL );
279 316
317//printf("7\n");
280 pthread_mutex_unlock( &mutex_lp_count ); 318 pthread_mutex_unlock( &mutex_lp_count );
281 319
320//printf("8\n");
282} 321}
283 322
284/* increase active lua process count */ 323/* increase active lua process count */
285void sched_lpcount_inc( void ) { 324void sched_lpcount_inc( void ) {
325//printf("inc procs++++++++++++++++++++++++++++++++++++++++\n");
286 pthread_mutex_lock( &mutex_lp_count ); 326 pthread_mutex_lock( &mutex_lp_count );
287 lpcount++; 327 lpcount++;
288 pthread_mutex_unlock( &mutex_lp_count ); 328 pthread_mutex_unlock( &mutex_lp_count );
@@ -290,10 +330,12 @@ void sched_lpcount_inc( void ) {
290 330
291/* decrease active lua process count */ 331/* decrease active lua process count */
292void sched_lpcount_dec( void ) { 332void sched_lpcount_dec( void ) {
333//printf("dec procs----------------------------------------\n");
293 pthread_mutex_lock( &mutex_lp_count ); 334 pthread_mutex_lock( &mutex_lp_count );
294 lpcount--; 335 lpcount--;
295 /* if count reaches zero, signal there are no more active processes */ 336 /* if count reaches zero, signal there are no more active processes */
296 if ( lpcount == 0 ) { 337 if ( lpcount == 0 ) {
338//printf("dec procs AND NONE LEFT000000000000000000000000000\n");
297 pthread_cond_signal( &cond_no_active_lp ); 339 pthread_cond_signal( &cond_no_active_lp );
298 } 340 }
299 pthread_mutex_unlock( &mutex_lp_count ); 341 pthread_mutex_unlock( &mutex_lp_count );