|
4 | 4 | #define RECEIVER_CAPI_IMPLEMENT_SET_CAPI 1 |
5 | 5 | #define SENDER_CAPI_IMPLEMENT_SET_CAPI 1 |
6 | 6 |
|
| 7 | +#define CARRAY_CAPI_IMPLEMENT_GET_CAPI 1 |
| 8 | + |
7 | 9 | #include "buffer.h" |
8 | 10 | #include "listener.h" |
9 | 11 | #include "serialize.h" |
|
12 | 14 | #include "receiver_capi_impl.h" |
13 | 15 | #include "sender_capi_impl.h" |
14 | 16 | #include "notify_capi_impl.h" |
| 17 | +#include "carray_capi.h" |
15 | 18 |
|
16 | 19 | const char* const MTMSG_BUFFER_CLASS_NAME = "mtmsg.buffer"; |
17 | 20 |
|
@@ -793,16 +796,41 @@ int mtmsg_buffer_next_msg(lua_State* L, BufferUserData* udata, |
793 | 796 | MsgBuffer* b, bool nonblock, int arg, double timeoutSeconds , MemBuffer* resultBuffer, size_t* argsSize, |
794 | 797 | sender_error_handler sender_eh, void* sender_ehdata) |
795 | 798 | { |
796 | | - lua_Number endTime = 0; /* 0 = no timeout */ |
797 | | - |
| 799 | + lua_Number endTime = -1; /* -1 = no timeout, wait forever */ |
| 800 | + int argTop = 0; |
798 | 801 | if (L) { |
799 | | - if (arg && !lua_isnoneornil(L, arg)) { |
800 | | - lua_Number waitSeconds = luaL_checknumber(L, arg); |
801 | | - endTime = mtmsg_current_time_seconds() + waitSeconds; |
| 802 | + argTop = lua_gettop(L); |
| 803 | + if (arg && arg <= argTop) { |
| 804 | + int t = lua_type(L, arg); |
| 805 | + if (t == LUA_TNIL || t == LUA_TNUMBER) { |
| 806 | + if (t == LUA_TNUMBER) { |
| 807 | + lua_Number waitSeconds = lua_tonumber(L, arg); |
| 808 | + if (waitSeconds < 0) waitSeconds = 0; |
| 809 | + endTime = mtmsg_current_time_seconds() + waitSeconds; |
| 810 | + if (waitSeconds == 0) { |
| 811 | + nonblock = true; |
| 812 | + } |
| 813 | + } |
| 814 | + arg += 1; |
| 815 | + } else { |
| 816 | + int reason = 0; |
| 817 | + if (t != LUA_TUSERDATA || !carray_get_capi(L, arg, &reason)) { |
| 818 | + if (reason == 1) { |
| 819 | + return luaL_argerror(L, arg, "incompatible carray capi version number"); |
| 820 | + } else if (!resultBuffer) { |
| 821 | + return luaL_argerror(L, arg, "timeout seconds or carray expected"); |
| 822 | + } else { |
| 823 | + return luaL_argerror(L, arg, "timeout seconds expected"); |
| 824 | + } |
| 825 | + } |
| 826 | + } |
802 | 827 | } |
803 | 828 | } else { |
804 | | - if (timeoutSeconds >= 0) { |
| 829 | + if (timeoutSeconds >= 0) { /* timeoutSeconds < 0 -> no timeout, wait forever */ |
805 | 830 | endTime = mtmsg_current_time_seconds() + timeoutSeconds; |
| 831 | + if (timeoutSeconds == 0) { |
| 832 | + nonblock = true; |
| 833 | + } |
806 | 834 | } |
807 | 835 | } |
808 | 836 |
|
@@ -848,13 +876,21 @@ int mtmsg_buffer_next_msg(lua_State* L, BufferUserData* udata, |
848 | 876 | par.inMaxArgCount = -1; |
849 | 877 | par.parsedLength = 0; |
850 | 878 | par.parsedArgCount = 0; |
851 | | - par.carrayCapi = udata->carrayCapi; |
| 879 | + par.carrayCapi = udata->carrayCapi; |
| 880 | + par.errorArg = 0; |
852 | 881 | lua_pushcfunction(L, mtmsg_serialize_get_msg_args); |
| 882 | + lua_insert(L, arg); |
853 | 883 | lua_pushlightuserdata(L, &par); |
854 | | - int rc = lua_pcall(L, 1, LUA_MULTRET, 0); |
| 884 | + lua_insert(L, arg + 1); |
| 885 | + int nargs = argTop - arg + 1; |
| 886 | + int rc = lua_pcall(L, nargs + 1, LUA_MULTRET, 0); |
855 | 887 | if (rc != LUA_OK) { |
856 | 888 | async_mutex_unlock(b->sharedMutex); |
857 | | - return lua_error(L); |
| 889 | + if (par.errorArg) { |
| 890 | + return luaL_argerror(L, arg + par.errorArg - 2, lua_tostring(L, -1)); |
| 891 | + } else { |
| 892 | + return lua_error(L); |
| 893 | + } |
858 | 894 | } |
859 | 895 | rslt = par.parsedArgCount; |
860 | 896 | udata->carrayCapi = par.carrayCapi; |
@@ -912,7 +948,7 @@ int mtmsg_buffer_next_msg(lua_State* L, BufferUserData* udata, |
912 | 948 | } |
913 | 949 | return rslt; |
914 | 950 | } else { |
915 | | - if (endTime > 0) { |
| 951 | + if (endTime >= 0) { |
916 | 952 | lua_Number now = mtmsg_current_time_seconds(); |
917 | 953 | if (now < endTime) { |
918 | 954 | async_mutex_wait_millis(b->sharedMutex, (int)((endTime - now) * 1000 + 0.5)); |
|
0 commit comments