aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--src/lanes.c109
-rw-r--r--src/threading.c52
-rw-r--r--src/threading.h1
4 files changed, 91 insertions, 77 deletions
diff --git a/CHANGES b/CHANGES
index 36f06ab..6eaca41 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
1CHANGES: 1CHANGES:
2 2
3CHAGE 46: BGe 10-Sep-2012 3CHANGE 47: BGe 13-Sep-2012
4 * implemented set_debug_threadname() for pthread builds where possible
5 * refactored linda __tostring and __concat
6
7CHANGE 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*/
716LUAG_FUNC( linda_tostring) 716
717static 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
738LUAG_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*/
738LUAG_FUNC( linda_concat) 751LUAG_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)
1526typedef 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
1535void 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
1554LUAG_FUNC( set_debug_threadname) 1523LUAG_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
740static 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
219void THREAD_KILL( THREAD_T *ref ); 219void THREAD_KILL( THREAD_T *ref );
220void THREAD_SETNAME( char const* _name);
220 221
221#endif // __threading_h__ 222#endif // __threading_h__