diff options
| author | Benoit Germain <bnt.germain@gmail.com> | 2012-09-13 22:40:16 +0200 |
|---|---|---|
| committer | Benoit Germain <bnt.germain@gmail.com> | 2012-09-13 22:40:16 +0200 |
| commit | 30b046f829541ae5ff8dc1088cea8e09bdc320db (patch) | |
| tree | b9d3e926b60aa0d88fafd477c94a23df6537321a | |
| parent | 5fad772d922250db9d46edec156cd89939c4d8b5 (diff) | |
| download | lanes-30b046f829541ae5ff8dc1088cea8e09bdc320db.tar.gz lanes-30b046f829541ae5ff8dc1088cea8e09bdc320db.tar.bz2 lanes-30b046f829541ae5ff8dc1088cea8e09bdc320db.zip | |
minor internal changes
* implemented set_debug_threadname() for pthread builds where possible
* refactored linda __tostring and __concat
* linda metatable's __metatable is a string instead of a boolean
| -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__ |
