From aa214c93b24de0fee5eb1e839e5c96f9dc40af3a Mon Sep 17 00:00:00 2001 From: ferrieux Date: Fri, 19 Aug 2011 15:13:26 +0000 Subject: [Bug 2981154] async-4.3 segfault. (backport) --- ChangeLog | 4 ++++ generic/tclTest.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index df5aef0..4c3d69a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-08-19 Alexandre Ferrieux + + * generic/tclTest.c: [Bug 2981154] async-4.3 segfault. + 2011-08-18 Jan Nijtmans * generic/tclUniData.c: [Bug 3393714] overflow in toupper delta diff --git a/generic/tclTest.c b/generic/tclTest.c index e0a4ef5..b43dbd2 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -61,6 +61,8 @@ typedef struct TestAsyncHandler { /* Next is list of handlers. */ } TestAsyncHandler; +TCL_DECLARE_MUTEX(asyncTestMutex); + static TestAsyncHandler *firstHandler = NULL; /* @@ -791,14 +793,16 @@ TestasyncCmd( goto wrongNumArgs; } asyncPtr = (TestAsyncHandler *) ckalloc(sizeof(TestAsyncHandler)); + asyncPtr->command = ckalloc(strlen(argv[2]) + 1); + strcpy(asyncPtr->command, argv[2]); + Tcl_MutexLock(&asyncTestMutex); asyncPtr->id = nextId; nextId++; asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc, - (ClientData) asyncPtr); - asyncPtr->command = (char *) ckalloc((unsigned) (strlen(argv[2]) + 1)); - strcpy(asyncPtr->command, argv[2]); + (ClientData) asyncPtr->id); asyncPtr->nextPtr = firstHandler; firstHandler = asyncPtr; + Tcl_MutexUnlock(&asyncTestMutex); TclFormatInt(buf, asyncPtr->id); Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if (strcmp(argv[1], "delete") == 0) { @@ -833,6 +837,7 @@ TestasyncCmd( ckfree((char *) asyncPtr); break; } + Tcl_MutexUnlock(&asyncTestMutex); } else if (strcmp(argv[1], "mark") == 0) { if (argc != 5) { goto wrongNumArgs; @@ -863,7 +868,7 @@ TestasyncCmd( if (asyncPtr->id == id) { Tcl_ThreadId threadID; if (Tcl_CreateThread(&threadID, AsyncThreadProc, - (ClientData) asyncPtr, TCL_THREAD_STACK_DEFAULT, + (ClientData) id, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) { Tcl_SetResult(interp, "can't create thread", TCL_STATIC); return TCL_ERROR; @@ -887,15 +892,29 @@ TestasyncCmd( static int AsyncHandlerProc( - ClientData clientData, /* Pointer to TestAsyncHandler structure. */ + ClientData clientData, /* If of TestAsyncHandler structure. + * in global list. */ Tcl_Interp *interp, /* Interpreter in which command was * executed, or NULL. */ int code) /* Current return code from command. */ { - TestAsyncHandler *asyncPtr = (TestAsyncHandler *) clientData; + TestAsyncHandler *asyncPtr; + int id = (int) clientData; const char *listArgv[4], *cmd; char string[TCL_INTEGER_SPACE]; + Tcl_MutexLock(&asyncTestMutex); + for (asyncPtr = firstHandler; asyncPtr != NULL; + asyncPtr = asyncPtr->nextPtr) { + if (asyncPtr->id == id) break; + } + Tcl_MutexUnlock(&asyncTestMutex); + + if (!asyncPtr) { + /* Woops - this one was deleted between the AsyncMark and now */ + return TCL_OK; + } + TclFormatInt(string, code); listArgv[0] = asyncPtr->command; listArgv[1] = Tcl_GetString(Tcl_GetObjResult(interp)); @@ -933,12 +952,22 @@ AsyncHandlerProc( #ifdef TCL_THREADS static Tcl_ThreadCreateType AsyncThreadProc( - ClientData clientData) /* Parameter is a pointer to a + ClientData clientData) /* Parameter is the id of a * TestAsyncHandler, defined above. */ { - TestAsyncHandler *asyncPtr = clientData; + TestAsyncHandler *asyncPtr; + int id = (int) clientData; + Tcl_Sleep(1); - Tcl_AsyncMark(asyncPtr->handler); + Tcl_MutexLock(&asyncTestMutex); + for (asyncPtr = firstHandler; asyncPtr != NULL; + asyncPtr = asyncPtr->nextPtr) { + if (asyncPtr->id == id) { + Tcl_AsyncMark(asyncPtr->handler); + break; + } + } + Tcl_MutexUnlock(&asyncTestMutex); Tcl_ExitThread(TCL_OK); TCL_THREAD_CREATE_RETURN; } @@ -7485,5 +7514,7 @@ TestconcatobjCmd( * mode: c * c-basic-offset: 4 * fill-column: 78 + * tab-width: 8 + * indent-tabs-mode: nil * End: */ -- cgit v0.12 From bddde2bfc901c841ab29bb1a2ed66008308d73f6 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Fri, 19 Aug 2011 15:24:32 +0000 Subject: [Bug 1774689] async-4.3 sometimes fails. (backport) --- ChangeLog | 1 + tests/async.test | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4c3d69a..c6dc4a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2011-08-19 Alexandre Ferrieux * generic/tclTest.c: [Bug 2981154] async-4.3 segfault. + * tests/async.test: [Bug 1774689] async-4.3 sometimes fails. 2011-08-18 Jan Nijtmans diff --git a/tests/async.test b/tests/async.test index f89413f..b369839 100644 --- a/tests/async.test +++ b/tests/async.test @@ -175,7 +175,7 @@ proc hang3 {handle} [concat { set aresult {Async event not delivered} testasync marklater $handle set i 0 -} [string repeat {;incr i;} 1500000] { +} "[string repeat {;incr i;} 1500000]after 10;" { return $aresult }] -- cgit v0.12 From 975f25e21740148f39d80952825b21b199e72834 Mon Sep 17 00:00:00 2001 From: andreask Date: Mon, 22 Aug 2011 16:28:43 +0000 Subject: Fixed use of C99 features breaking the build with MSVC6. The problem was introduced with checkin [e9a08358f4]. --- ChangeLog | 6 ++++++ win/tclWinDde.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8391aeb..fb2e9c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-08-22 Andreas Kupries + + * win/tclWinDde.c (Tcl_DdeObjCmd): Fixed use of the C99 feature + (Variable declaration within statement block) rejected by + MSVC6. Moved the declaration to the beginning of the block. + 2011-08-18 Jan Nijtmans * generic/tclUniData.c: [Bug 3393714] overflow in toupper delta diff --git a/win/tclWinDde.c b/win/tclWinDde.c index d180878..0d5f7d7 100644 --- a/win/tclWinDde.c +++ b/win/tclWinDde.c @@ -1254,8 +1254,8 @@ Tcl_DdeObjCmd( break; } case DDE_POKE: { - itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length); BYTE *dataString; + itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length); if (length == 0) { Tcl_SetStringObj(Tcl_GetObjResult(interp), "cannot have a null item", -1); -- cgit v0.12 From b001a09fa9bea8a30e18638849438a54fc58c5f2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 Aug 2011 07:08:34 +0000 Subject: [FRQ 3396731] inline string reverse --- ChangeLog | 4 ++ generic/tclStringObj.c | 160 ++++++++++++++++++++++++------------------------- 2 files changed, 84 insertions(+), 80 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e7821a..36cf7f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-08-23 Jan Nijtmans + + * generic/tclStringObj.c: [FRQ 3396731] inline string reverse + 2011-08-19 Don Porter * generic/tclIORTrans.c: [Bugs 3393279, 3393280] ReflectClose(.) is diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index ab62359..993a694 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2657,96 +2657,96 @@ Tcl_Obj * TclStringObjReverse( Tcl_Obj *objPtr) { - String *stringPtr; - char *src = NULL, *dest = NULL; - Tcl_UniChar *usrc = NULL, *udest = NULL; - Tcl_Obj *resultPtr = NULL; + char *src, *dest; + Tcl_Obj *resultPtr = objPtr; + char c; - SetStringFromAny(NULL, objPtr); - stringPtr = GET_STRING(objPtr); + src = TclGetString(objPtr); + if (Tcl_IsShared(objPtr)) { + resultPtr = Tcl_NewObj(); + Tcl_SetObjLength(resultPtr, objPtr->length); + dest = TclGetString(resultPtr); + memcpy(dest, src, objPtr->length); + } else { + TclFreeIntRep(objPtr); + dest = src; + } - if (stringPtr->hasUnicode == 0) { - if (stringPtr->numChars == -1) { - TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length); - } - if (stringPtr->numChars <= 1) { - return objPtr; - } - if (stringPtr->numChars == objPtr->length) { - /* - * All one-byte chars. Reverse in objPtr->bytes. - */ + src = dest + objPtr->length; - if (Tcl_IsShared(objPtr)) { - resultPtr = Tcl_NewObj(); - Tcl_SetObjLength(resultPtr, objPtr->length); - dest = TclGetString(resultPtr); - src = objPtr->bytes + objPtr->length - 1; - while (src >= objPtr->bytes) { - *dest++ = *src--; - } - return resultPtr; + /* Pass 1: reverse individual bytes of UTF-8 representation. */ + while (dest < src) { + Tcl_UniChar ch = 0; + switch (Tcl_UtfToUniChar(dest, &ch)) { + case 1: { + ++dest; + break; } - - /* - * Unshared. Reverse objPtr->bytes in place. - */ - - dest = objPtr->bytes; - src = dest + objPtr->length - 1; - while (dest < src) { - char tmp = *src; - - *src-- = *dest; - *dest++ = tmp; + case 2: { + c = dest[0]; + dest[0] = dest[1]; + dest[1] = c; + dest += 2; + break; + } + case 3: { + c = dest[0]; + dest[0] = dest[2]; + dest[2] = c; + dest += 3; + break; + } +#if TCL_UTF_MAX > 4 + case 5: { + c = dest[0]; + dest[0] = dest[4]; + dest[4] = c; + c = dest[1]; + dest[1] = dest[3]; + dest[3] = c; + dest += 5; + break; + } +#endif +#if TCL_UTF_MAX > 5 + case 6: { + c = dest[0]; + dest[0] = dest[5]; + dest[5] = c; + c = dest[1]; + dest[1] = dest[4]; + dest[4] = c; + c = dest[0]; + dest[2] = dest[3]; + dest[3] = c; + dest += 6; + break; + } +#endif + default: { +#if TCL_UTF_MAX > 3 + c = dest[0]; + dest[0] = dest[3]; + dest[3] = c; + c = dest[1]; + dest[1] = dest[2]; + dest[2] = c; + dest += 4; +#endif + break; } - return objPtr; } - FillUnicodeRep(objPtr); - stringPtr = GET_STRING(objPtr); - } - if (stringPtr->numChars <= 1) { - return objPtr; } - /* - * Reverse the Unicode rep. - */ - - if (Tcl_IsShared(objPtr)) { - Tcl_UniChar ch = 0; - - /* - * Create a non-empty, pure unicode value, so we can coax - * Tcl_SetObjLength into growing the unicode rep buffer. - */ + /* Pass 2: Reverse byte string. */ + dest = TclGetString(resultPtr); - resultPtr = Tcl_NewUnicodeObj(&ch, 1); - Tcl_SetObjLength(resultPtr, stringPtr->numChars); - udest = Tcl_GetUnicode(resultPtr); - usrc = stringPtr->unicode + stringPtr->numChars - 1; - while (usrc >= stringPtr->unicode) { - *udest++ = *usrc--; + while (dest < --src) { + c = *src; + *src = *dest; + *dest++ = c; } - return resultPtr; - } - - /* - * Unshared. Reverse objPtr->bytes in place. - */ - - udest = stringPtr->unicode; - usrc = udest + stringPtr->numChars - 1; - while (udest < usrc) { - Tcl_UniChar tmp = *usrc; - - *usrc-- = *udest; - *udest++ = tmp; - } - - TclInvalidateStringRep(objPtr); - stringPtr->allocated = 0; - return objPtr; + return resultPtr; } /* -- cgit v0.12 From 379048cb89b55b63858d61a573dbe5537b3656e5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 Aug 2011 07:15:33 +0000 Subject: gcc 4.6 (64-bit) warnings --- generic/tclTest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index b43dbd2..2430d1a 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -799,7 +799,7 @@ TestasyncCmd( asyncPtr->id = nextId; nextId++; asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc, - (ClientData) asyncPtr->id); + INT2PTR(asyncPtr->id)); asyncPtr->nextPtr = firstHandler; firstHandler = asyncPtr; Tcl_MutexUnlock(&asyncTestMutex); @@ -899,7 +899,7 @@ AsyncHandlerProc( int code) /* Current return code from command. */ { TestAsyncHandler *asyncPtr; - int id = (int) clientData; + int id = PTR2INT(clientData); const char *listArgv[4], *cmd; char string[TCL_INTEGER_SPACE]; -- cgit v0.12