Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | backport [e393e41a8d]: Fix several more missing mutex-locks in TestasyncCmd |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-4-branch |
Files: | files | file ages | folders |
SHA1: |
861e1fd6e93b93e5755b5b1a88333cd7 |
User & Date: | jan.nijtmans 2012-07-20 08:41:38 |
Context
2012-07-24
| ||
20:18 | Preserve the chanPtr so that script evaluation cannot invalidate it when we plan to use it again. check-in: ea138c4fb3 user: dgp tags: core-8-4-branch | |
2012-07-20
| ||
08:43 | merge-mark check-in: 8c75ef0d5f user: jan.nijtmans tags: core-8-5-branch | |
08:41 | backport [e393e41a8d]: Fix several more missing mutex-locks in TestasyncCmd check-in: 861e1fd6e9 user: jan.nijtmans tags: core-8-4-branch | |
08:23 | Add instrunctions how to (cross-)compile win32/win64 binaries on Linux, Darwin or Cygwin check-in: f736e68322 user: jan.nijtmans tags: core-8-4-branch | |
Changes
Changes to generic/tclTest.c.
︙ | ︙ | |||
60 61 62 63 64 65 66 67 68 69 70 71 72 73 | typedef struct TestAsyncHandler { int id; /* Identifier for this handler. */ Tcl_AsyncHandler handler; /* Tcl's token for the handler. */ char *command; /* Command to invoke when the * handler is invoked. */ struct TestAsyncHandler *nextPtr; /* Next is list of handlers. */ } TestAsyncHandler; static TestAsyncHandler *firstHandler = NULL; /* * The dynamic string below is used by the "testdstring" command * to test the dynamic string facilities. */ | > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | typedef struct TestAsyncHandler { int id; /* Identifier for this handler. */ Tcl_AsyncHandler handler; /* Tcl's token for the handler. */ char *command; /* Command to invoke when the * handler is invoked. */ struct TestAsyncHandler *nextPtr; /* Next is list of handlers. */ } TestAsyncHandler; TCL_DECLARE_MUTEX(asyncTestMutex); static TestAsyncHandler *firstHandler = NULL; /* * The dynamic string below is used by the "testdstring" command * to test the dynamic string facilities. */ |
︙ | ︙ | |||
795 796 797 798 799 800 801 802 803 804 | return TCL_ERROR; } if (strcmp(argv[1], "create") == 0) { if (argc != 3) { goto wrongNumArgs; } asyncPtr = (TestAsyncHandler *) ckalloc(sizeof(TestAsyncHandler)); asyncPtr->id = nextId; nextId++; asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc, | > > > | < < > > > > > > | > | > > > > > > > > > > > > > | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 | return TCL_ERROR; } if (strcmp(argv[1], "create") == 0) { if (argc != 3) { goto wrongNumArgs; } asyncPtr = (TestAsyncHandler *) ckalloc(sizeof(TestAsyncHandler)); asyncPtr->command = (char *) ckalloc((unsigned) (strlen(argv[2]) + 1)); strcpy(asyncPtr->command, argv[2]); Tcl_MutexLock(&asyncTestMutex); asyncPtr->id = nextId; nextId++; asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc, (ClientData) asyncPtr->id); asyncPtr->nextPtr = firstHandler; firstHandler = asyncPtr; TclFormatInt(buf, asyncPtr->id); Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if (strcmp(argv[1], "delete") == 0) { if (argc == 2) { Tcl_MutexLock(&asyncTestMutex); while (firstHandler != NULL) { asyncPtr = firstHandler; firstHandler = asyncPtr->nextPtr; Tcl_AsyncDelete(asyncPtr->handler); ckfree(asyncPtr->command); ckfree((char *) asyncPtr); } Tcl_MutexUnlock(&asyncTestMutex); return TCL_OK; } if (argc != 3) { goto wrongNumArgs; } if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) { return TCL_ERROR; } Tcl_MutexLock(&asyncTestMutex); for (prevPtr = NULL, asyncPtr = firstHandler; asyncPtr != NULL; prevPtr = asyncPtr, asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id != id) { continue; } if (prevPtr == NULL) { firstHandler = asyncPtr->nextPtr; } else { prevPtr->nextPtr = asyncPtr->nextPtr; } Tcl_AsyncDelete(asyncPtr->handler); ckfree(asyncPtr->command); ckfree((char *) asyncPtr); break; } Tcl_MutexUnlock(&asyncTestMutex); } else if (strcmp(argv[1], "mark") == 0) { if (argc != 5) { goto wrongNumArgs; } if ((Tcl_GetInt(interp, argv[2], &id) != TCL_OK) || (Tcl_GetInt(interp, argv[4], &code) != TCL_OK)) { return TCL_ERROR; } Tcl_MutexLock(&asyncTestMutex); for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_AsyncMark(asyncPtr->handler); break; } } Tcl_MutexUnlock(&asyncTestMutex); Tcl_SetResult(interp, (char *)argv[3], TCL_VOLATILE); return code; } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create, delete, int, or mark", (char *) NULL); return TCL_ERROR; } return TCL_OK; } static int AsyncHandlerProc(clientData, interp, code) ClientData clientData; /* Id 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; 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)); listArgv[2] = string; listArgv[3] = NULL; cmd = Tcl_Merge(3, listArgv); |
︙ | ︙ |