diff options
Diffstat (limited to '')
-rw-r--r-- | LuaSL/src/LuaSL_threads.c | 52 |
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 ) { | |||
454 | static script *luaproc_getself(lua_State *L) | 455 | static 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 */ |
507 | static int luaproc_send_back( lua_State *L ) { | 509 | static 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 */ |
538 | const char *sendToChannel(const char *chname, const char *message, script **dst, channel *chn) | 539 | const 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, | |||
596 | static int luaproc_send( lua_State *L ) { | 618 | static 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; |