aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/src/LuaSL_threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'LuaSL/src/LuaSL_threads.c')
-rw-r--r--LuaSL/src/LuaSL_threads.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/LuaSL/src/LuaSL_threads.c b/LuaSL/src/LuaSL_threads.c
index d24f224..4a7397e 100644
--- a/LuaSL/src/LuaSL_threads.c
+++ b/LuaSL/src/LuaSL_threads.c
@@ -410,6 +410,7 @@ void newProc(const char *code, int file, script *lp)
410 lp->args = 0; 410 lp->args = 0;
411 lp->chan = NULL; 411 lp->chan = NULL;
412 eina_clist_element_init(&(lp->node)); 412 eina_clist_element_init(&(lp->node));
413 eina_clist_init(&(lp->messages));
413 414
414 /* load process' code */ 415 /* load process' code */
415 if (file) 416 if (file)
@@ -454,6 +455,7 @@ static void luaproc_movevalues( lua_State *Lfrom, lua_State *Lto ) {
454static script *luaproc_getself(lua_State *L) 455static script *luaproc_getself(lua_State *L)
455{ 456{
456 script *lp; 457 script *lp;
458
457 lua_getfield(L, LUA_REGISTRYINDEX, "_SELF"); 459 lua_getfield(L, LUA_REGISTRYINDEX, "_SELF");
458 lp = (script *) lua_touserdata(L, -1); 460 lp = (script *) lua_touserdata(L, -1);
459 lua_pop(L, 1); 461 lua_pop(L, 1);
@@ -503,7 +505,7 @@ static int luaproc_create_channel(lua_State *L)
503 return 1; 505 return 1;
504} 506}
505 507
506/* send a message to a lua process */ 508/* send a message to the client process */
507static int luaproc_send_back( lua_State *L ) { 509static int luaproc_send_back( lua_State *L ) {
508 510
509 script *self; 511 script *self;
@@ -516,6 +518,7 @@ static int luaproc_send_back( lua_State *L ) {
516 518
517 if (sm) 519 if (sm)
518 { 520 {
521 eina_clist_element_init(&(sm->node));
519 sm->script = self; 522 sm->script = self;
520 strcpy((char *) sm->message, message); 523 strcpy((char *) sm->message, message);
521 ecore_main_loop_thread_safe_call_async(scriptSendBack, sm); 524 ecore_main_loop_thread_safe_call_async(scriptSendBack, sm);
@@ -532,18 +535,28 @@ const char *sendToChannelErrors[] =
532 "error scheduling process" 535 "error scheduling process"
533}; 536};
534 537
535// TODO - If these come in too quick, then messages might get lost. Also, in at least one case, it locked up this thread I think.
536
537/* send a message to a lua process */ 538/* send a message to a lua process */
538const char *sendToChannel(const char *chname, const char *message, script **dst, channel *chn) 539const char *sendToChannel(gameGlobals *game, const char *chname, const char *message, script **dst, channel *chn)
539{ 540{
540 const char *result = NULL; 541 const char *result = NULL;
541 channel chan; 542 channel chan;
542 script *dstlp; 543 script *dstlp;
544 scriptMessage *sm = NULL;
543 545
544 /* get exclusive access to operate on channels */ 546 /* get exclusive access to operate on channels */
545 pthread_mutex_lock(&mutex_channel); 547 pthread_mutex_lock(&mutex_channel);
546 548
549 // Add the message to the queue.
550 if ((dstlp = eina_hash_find(game->scripts, chname)))
551 {
552 if ((sm = malloc(sizeof(scriptMessage))))
553 {
554 sm->script = dstlp;
555 strcpy((char *) sm->message, message);
556 eina_clist_add_tail(&(sm->script->messages), &(sm->node));
557 }
558 }
559
547 /* wait until channel is not in use */ 560 /* wait until channel is not in use */
548 while( ((chan = eina_hash_find(channels, chname)) != NULL) && (pthread_mutex_trylock(chan->mutex) != 0 )) 561 while( ((chan = eina_hash_find(channels, chname)) != NULL) && (pthread_mutex_trylock(chan->mutex) != 0 ))
549 { 562 {
@@ -563,10 +576,19 @@ const char *sendToChannel(const char *chname, const char *message, script **dst,
563 /* if a match is found, send the message to it and (queue) wake it */ 576 /* if a match is found, send the message to it and (queue) wake it */
564 if (dstlp != NULL) 577 if (dstlp != NULL)
565 { 578 {
566 /* push the message onto the receivers stack */ 579 scriptMessage *msg = (scriptMessage *) eina_clist_head(&(dstlp->messages));
567 lua_pushstring( dstlp->L, message);
568 580
581 // See if there's a message on the queue. Note, this may not be the same as the incoming message, if there was already a queue.
582 if (msg)
583 {
584 eina_clist_remove(&(msg->node));
585 message = msg->message;
586 }
587 /* push the message onto the receivers stack */
588 lua_pushstring(dstlp->L, message);
569 dstlp->args = lua_gettop(dstlp->L) - 1; 589 dstlp->args = lua_gettop(dstlp->L) - 1;
590 if (msg)
591 free(msg);
570 592
571 if (sched_queue_proc(dstlp) != LUAPROC_SCHED_QUEUE_PROC_OK) 593 if (sched_queue_proc(dstlp) != LUAPROC_SCHED_QUEUE_PROC_OK)
572 { 594 {
@@ -596,10 +618,10 @@ const char *sendToChannel(const char *chname, const char *message, script **dst,
596static int luaproc_send( lua_State *L ) { 618static int luaproc_send( lua_State *L ) {
597 619
598 channel chan; 620 channel chan;
599 script *dstlp, *self; 621 script *dstlp, *self = luaproc_getself(L);
600 const char *chname = luaL_checkstring( L, 1 ); 622 const char *chname = luaL_checkstring( L, 1 );
601 const char *message = luaL_checkstring( L, 2 ); 623 const char *message = luaL_checkstring( L, 2 );
602 const char *result = sendToChannel(chname, message, &dstlp, &chan); 624 const char *result = sendToChannel(self->game, chname, message, &dstlp, &chan);
603 625
604 if (result) { 626 if (result) {
605 lua_pushnil( L ); 627 lua_pushnil( L );
@@ -609,8 +631,6 @@ static int luaproc_send( lua_State *L ) {
609 631
610 if ( dstlp == NULL ) { 632 if ( dstlp == NULL ) {
611 633
612 self = luaproc_getself( L );
613
614 if ( self != NULL ) { 634 if ( self != NULL ) {
615 self->status = LUAPROC_STAT_BLOCKED_SEND; 635 self->status = LUAPROC_STAT_BLOCKED_SEND;
616 self->chan = chan; 636 self->chan = chan;
@@ -630,6 +650,17 @@ static int luaproc_receive( lua_State *L ) {
630 channel chan; 650 channel chan;
631 script *srclp, *self; 651 script *srclp, *self;
632 const char *chname = luaL_checkstring( L, 1 ); 652 const char *chname = luaL_checkstring( L, 1 );
653 scriptMessage *msg;
654
655 // First check if there are queued messages, and grab one.
656 self = luaproc_getself(L);
657 if ((msg = (scriptMessage *) eina_clist_head(&(self->messages))))
658 {
659 eina_clist_remove(&(msg->node));
660 lua_pushstring(L, msg->message);
661 free(msg);
662 return lua_gettop(L) - 1;
663 }
633 664
634 /* get exclusive access to operate on channels */ 665 /* get exclusive access to operate on channels */
635 pthread_mutex_lock( &mutex_channel ); 666 pthread_mutex_lock( &mutex_channel );
@@ -698,7 +729,6 @@ static int luaproc_receive( lua_State *L ) {
698 729
699 /* otherwise (synchronous receive) simply block process */ 730 /* otherwise (synchronous receive) simply block process */
700 else { 731 else {
701 self = luaproc_getself( L );
702 732
703 if ( self != NULL ) { 733 if ( self != NULL ) {
704 self->status = LUAPROC_STAT_BLOCKED_RECV; 734 self->status = LUAPROC_STAT_BLOCKED_RECV;