diff options
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | src/lanes.c | 109 | ||||
-rw-r--r-- | src/threading.c | 52 | ||||
-rw-r--r-- | src/threading.h | 1 |
4 files changed, 91 insertions, 77 deletions
@@ -1,6 +1,10 @@ | |||
1 | CHANGES: | 1 | CHANGES: |
2 | 2 | ||
3 | CHAGE 46: BGe 10-Sep-2012 | 3 | CHANGE 47: BGe 13-Sep-2012 |
4 | * implemented set_debug_threadname() for pthread builds where possible | ||
5 | * refactored linda __tostring and __concat | ||
6 | |||
7 | CHANGE 46: BGe 10-Sep-2012 | ||
4 | * version 3.3.0 | 8 | * version 3.3.0 |
5 | * lane.status can return "killed" if lane was forcefully killed with lanes:cancel() | 9 | * lane.status can return "killed" if lane was forcefully killed with lanes:cancel() |
6 | * lane:join(): return nil, "killed" if called on a killed lane. | 10 | * lane:join(): return nil, "killed" if called on a killed lane. |
diff --git a/src/lanes.c b/src/lanes.c index 3ac085d..eac4753 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -713,18 +713,31 @@ LUAG_FUNC( linda_deep ) { | |||
713 | * | 713 | * |
714 | * Useful for concatenation or debugging purposes | 714 | * Useful for concatenation or debugging purposes |
715 | */ | 715 | */ |
716 | LUAG_FUNC( linda_tostring) | 716 | |
717 | static int linda_tostring( lua_State* L, int _idx, bool_t _opt) | ||
717 | { | 718 | { |
718 | char text[32]; | 719 | char text[32]; |
719 | int len; | 720 | int len; |
720 | struct s_Linda* linda = lua_toLinda( L, 1); | 721 | struct s_Linda* linda = lua_toLinda( L, _idx); |
721 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | 722 | if( !_opt) |
722 | if( linda->name[0]) | 723 | { |
723 | len = sprintf( text, "linda: %.*s", (int)sizeof(text) - 8, linda->name); | 724 | luaL_argcheck( L, linda, _idx, "expected a linda object!"); |
724 | else | 725 | } |
725 | len = sprintf( text, "linda: %p", linda); | 726 | if( linda) |
726 | lua_pushlstring( L, text, len); | 727 | { |
727 | return 1; | 728 | if( linda->name[0]) |
729 | len = sprintf( text, "Linda: %.*s", (int)sizeof(text) - 8, linda->name); | ||
730 | else | ||
731 | len = sprintf( text, "Linda: %p", linda); | ||
732 | lua_pushlstring( L, text, len); | ||
733 | return 1; | ||
734 | } | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | LUAG_FUNC( linda_tostring) | ||
739 | { | ||
740 | return linda_tostring( L, 1, FALSE); | ||
728 | } | 741 | } |
729 | 742 | ||
730 | 743 | ||
@@ -736,35 +749,23 @@ LUAG_FUNC( linda_tostring) | |||
736 | * Useful for concatenation or debugging purposes | 749 | * Useful for concatenation or debugging purposes |
737 | */ | 750 | */ |
738 | LUAG_FUNC( linda_concat) | 751 | LUAG_FUNC( linda_concat) |
739 | { | 752 | { // linda1? linda2? |
740 | struct s_Linda *linda1 = lua_toLinda( L, 1); | 753 | bool_t atLeastOneLinda = FALSE; |
741 | struct s_Linda *linda2 = lua_toLinda( L, 2); | 754 | // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. |
742 | // lua semantics should enforce that one of the parameters we got is a linda | 755 | if( linda_tostring( L, 1, TRUE)) |
743 | luaL_argcheck( L, linda1 || linda2, 1, "expected a linda object!"); | ||
744 | // replace the lindas by their string equivalents in the stack | ||
745 | if ( linda1) | ||
746 | { | 756 | { |
747 | char text[32]; | 757 | atLeastOneLinda = TRUE; |
748 | int len; | ||
749 | if( linda1->name[0]) | ||
750 | len = sprintf( text, "linda: %.*s", (int)sizeof(text) - 8, linda1->name); | ||
751 | else | ||
752 | len = sprintf( text, "linda: %p", linda1); | ||
753 | lua_pushlstring( L, text, len); | ||
754 | lua_replace( L, 1); | 758 | lua_replace( L, 1); |
755 | } | 759 | } |
756 | if ( linda2) | 760 | if( linda_tostring( L, 2, TRUE)) |
757 | { | 761 | { |
758 | char text[32]; | 762 | atLeastOneLinda = TRUE; |
759 | int len; | ||
760 | if( linda2->name[0]) | ||
761 | len = sprintf( text, "linda: %.*s", (int)sizeof(text) - 8, linda2->name); | ||
762 | else | ||
763 | len = sprintf( text, "linda: %p", linda2); | ||
764 | lua_pushlstring( L, text, len); | ||
765 | lua_replace( L, 2); | 763 | lua_replace( L, 2); |
766 | } | 764 | } |
767 | // concat the result | 765 | if( !atLeastOneLinda) // should not be possible |
766 | { | ||
767 | return luaL_error( L, "internal error: linda_concat called on non-Linda"); | ||
768 | } | ||
768 | lua_concat( L, 2); | 769 | lua_concat( L, 2); |
769 | return 1; | 770 | return 1; |
770 | } | 771 | } |
@@ -853,7 +854,7 @@ static void linda_id( lua_State *L, char const * const which) | |||
853 | lua_setfield( L, -2, "__index"); | 854 | lua_setfield( L, -2, "__index"); |
854 | 855 | ||
855 | // protect metatable from external access | 856 | // protect metatable from external access |
856 | lua_pushboolean( L, 0); | 857 | lua_pushliteral( L, "Linda"); |
857 | lua_setfield( L, -2, "__metatable"); | 858 | lua_setfield( L, -2, "__metatable"); |
858 | 859 | ||
859 | lua_pushcfunction( L, LG_linda_tostring); | 860 | lua_pushcfunction( L, LG_linda_tostring); |
@@ -1519,52 +1520,12 @@ static int lane_error( lua_State* L) | |||
1519 | } | 1520 | } |
1520 | #endif // ERROR_FULL_STACK | 1521 | #endif // ERROR_FULL_STACK |
1521 | 1522 | ||
1522 | #if defined PLATFORM_WIN32 && !defined __GNUC__ | ||
1523 | //see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx | ||
1524 | #define MS_VC_EXCEPTION 0x406D1388 | ||
1525 | #pragma pack(push,8) | ||
1526 | typedef struct tagTHREADNAME_INFO | ||
1527 | { | ||
1528 | DWORD dwType; // Must be 0x1000. | ||
1529 | LPCSTR szName; // Pointer to name (in user addr space). | ||
1530 | DWORD dwThreadID; // Thread ID (-1=caller thread). | ||
1531 | DWORD dwFlags; // Reserved for future use, must be zero. | ||
1532 | } THREADNAME_INFO; | ||
1533 | #pragma pack(pop) | ||
1534 | |||
1535 | void SetThreadName( DWORD dwThreadID, char const *_threadName) | ||
1536 | { | ||
1537 | THREADNAME_INFO info; | ||
1538 | Sleep(10); | ||
1539 | info.dwType = 0x1000; | ||
1540 | info.szName = _threadName; | ||
1541 | info.dwThreadID = dwThreadID; | ||
1542 | info.dwFlags = 0; | ||
1543 | |||
1544 | __try | ||
1545 | { | ||
1546 | RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); | ||
1547 | } | ||
1548 | __except(EXCEPTION_EXECUTE_HANDLER) | ||
1549 | { | ||
1550 | } | ||
1551 | } | ||
1552 | #endif | ||
1553 | |||
1554 | LUAG_FUNC( set_debug_threadname) | 1523 | LUAG_FUNC( set_debug_threadname) |
1555 | { | 1524 | { |
1556 | luaL_checktype( L, -1, LUA_TSTRING); | 1525 | luaL_checktype( L, -1, LUA_TSTRING); |
1557 | #if defined PLATFORM_WIN32 && !defined __GNUC__ | 1526 | THREAD_SETNAME( lua_tostring( L, -1)); |
1558 | { | ||
1559 | char const *threadName = lua_tostring( L, -1); | ||
1560 | |||
1561 | // to see thead name in Visual Studio C debugger | ||
1562 | SetThreadName(-1, threadName); | ||
1563 | } | ||
1564 | #endif // defined PLATFORM_WIN32 && !defined __GNUC__ | ||
1565 | // to see VM name in Decoda debugger Virtual Machine window | 1527 | // to see VM name in Decoda debugger Virtual Machine window |
1566 | lua_setglobal( L, "decoda_name"); | 1528 | lua_setglobal( L, "decoda_name"); |
1567 | |||
1568 | return 0; | 1529 | return 0; |
1569 | } | 1530 | } |
1570 | 1531 | ||
diff --git a/src/threading.c b/src/threading.c index 7cd8da3..3bcf6cd 100644 --- a/src/threading.c +++ b/src/threading.c | |||
@@ -303,6 +303,41 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | |||
303 | if (!TerminateThread( *ref, 0 )) FAIL("TerminateThread", GetLastError()); | 303 | if (!TerminateThread( *ref, 0 )) FAIL("TerminateThread", GetLastError()); |
304 | *ref= NULL; | 304 | *ref= NULL; |
305 | } | 305 | } |
306 | |||
307 | #if !defined __GNUC__ | ||
308 | //see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx | ||
309 | #define MS_VC_EXCEPTION 0x406D1388 | ||
310 | #pragma pack(push,8) | ||
311 | typedef struct tagTHREADNAME_INFO | ||
312 | { | ||
313 | DWORD dwType; // Must be 0x1000. | ||
314 | LPCSTR szName; // Pointer to name (in user addr space). | ||
315 | DWORD dwThreadID; // Thread ID (-1=caller thread). | ||
316 | DWORD dwFlags; // Reserved for future use, must be zero. | ||
317 | } THREADNAME_INFO; | ||
318 | #pragma pack(pop) | ||
319 | #endif // !__GNUC__ | ||
320 | |||
321 | void THREAD_SETNAME( char const* _name) | ||
322 | { | ||
323 | #if !defined __GNUC__ | ||
324 | THREADNAME_INFO info; | ||
325 | info.dwType = 0x1000; | ||
326 | info.szName = _name; | ||
327 | info.dwThreadID = GetCurrentThreadId(); | ||
328 | info.dwFlags = 0; | ||
329 | |||
330 | __try | ||
331 | { | ||
332 | RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); | ||
333 | } | ||
334 | __except(EXCEPTION_EXECUTE_HANDLER) | ||
335 | { | ||
336 | } | ||
337 | #endif // !__GNUC__ | ||
338 | } | ||
339 | |||
340 | |||
306 | // | 341 | // |
307 | void SIGNAL_INIT( SIGNAL_T *ref ) { | 342 | void SIGNAL_INIT( SIGNAL_T *ref ) { |
308 | // 'manual reset' event type selected, to be able to wake up all the | 343 | // 'manual reset' event type selected, to be able to wake up all the |
@@ -735,6 +770,19 @@ bool_t THREAD_WAIT( THREAD_T *ref, double secs , SIGNAL_T *signal_ref, MUTEX_T * | |||
735 | void THREAD_KILL( THREAD_T *ref ) { | 770 | void THREAD_KILL( THREAD_T *ref ) { |
736 | pthread_cancel( *ref ); | 771 | pthread_cancel( *ref ); |
737 | } | 772 | } |
738 | #endif // THREADAPI == THREADAPI_PTHREAD | ||
739 | 773 | ||
740 | static const lua_Alloc alloc_f= 0; | 774 | void THREAD_SETNAME( char const* _name) |
775 | { | ||
776 | // exact API to set the thread name is platform-dependant | ||
777 | // if you need to fix the build, or if you know how to fill a hole, tell me (bnt.germain@gmail.com) so that I can submit the fix in github. | ||
778 | #if defined PLATFORM_BSD | ||
779 | pthread_set_name_np( pthread_self(), _name); | ||
780 | #elif defined PLATFORM_LINUX || defined PLATFORM_QNX || defined PLATFORM_CYGWIN | ||
781 | pthread_setname_np(_name pthread_self(), _name); | ||
782 | #elif defined PLATFORM_OSX | ||
783 | pthread_setname_np(_name); | ||
784 | #elif defined PLATFORM_WIN32 || defined PLATFORM_POCKETPC | ||
785 | // no API in win32-pthread yet :-( | ||
786 | #endif | ||
787 | } | ||
788 | #endif // THREADAPI == THREADAPI_PTHREAD | ||
diff --git a/src/threading.h b/src/threading.h index b95733d..1d304fa 100644 --- a/src/threading.h +++ b/src/threading.h | |||
@@ -217,5 +217,6 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs, SIGNAL_T *signal_ref, MUTEX | |||
217 | #endif // // THREADWAIT_METHOD == THREADWAIT_CONDVAR | 217 | #endif // // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
218 | 218 | ||
219 | void THREAD_KILL( THREAD_T *ref ); | 219 | void THREAD_KILL( THREAD_T *ref ); |
220 | void THREAD_SETNAME( char const* _name); | ||
220 | 221 | ||
221 | #endif // __threading_h__ | 222 | #endif // __threading_h__ |