Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix indenting |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | main |
Files: | files | file ages | folders |
SHA3-256: |
2ac5b24c75a483966e874b9dd020b9c1 |
User & Date: | jan.nijtmans 2024-04-19 08:00:18 |
Context
2024-04-19
| ||
08:22 | Merge 8.7 (more indenting) check-in: ad350b1aa5 user: jan.nijtmans tags: trunk, main | |
08:12 | (backport) Fix indenting check-in: c3b5ee0e35 user: jan.nijtmans tags: core-8-branch | |
08:00 | Fix indenting check-in: 2ac5b24c75 user: jan.nijtmans tags: trunk, main | |
2024-04-18
| ||
15:25 | Merge 8.7 check-in: d6f9aacbe7 user: jan.nijtmans tags: trunk, main | |
Changes
Changes to generic/tclIO.c.
︙ | ︙ | |||
3148 3149 3150 3151 3152 3153 3154 | Tcl_SetErrno(errorCode); } } /* * Cancel any outstanding timer. */ | < > | 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 | Tcl_SetErrno(errorCode); } } /* * Cancel any outstanding timer. */ DeleteTimerHandler(statePtr); /* * Mark the channel as deleted by clearing the type structure. */ if (chanPtr->downChanPtr != NULL) { Channel *downChanPtr = chanPtr->downChanPtr; |
︙ | ︙ | |||
7540 7541 7542 7543 7544 7545 7546 | if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) { return 0; } return GotFlag(statePtr, CHANNEL_EOF) ? 1 : 0; } | < | 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 | if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) { return 0; } return GotFlag(statePtr, CHANNEL_EOF) ? 1 : 0; } /* *---------------------------------------------------------------------- * * TclChannelGetBlockingMode -- * * Returns 1 if the channel is in blocking mode (default), 0 otherwise. * |
︙ | ︙ | |||
7566 7567 7568 7569 7570 7571 7572 | Tcl_Channel chan) { ChannelState *statePtr = ((Channel *) chan)->state; /* State of real channel structure. */ return GotFlag(statePtr, CHANNEL_NONBLOCKING) ? 0 : 1; } | | | 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 | Tcl_Channel chan) { ChannelState *statePtr = ((Channel *) chan)->state; /* State of real channel structure. */ return GotFlag(statePtr, CHANNEL_NONBLOCKING) ? 0 : 1; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * |
︙ | ︙ |
Changes to generic/tclIORChan.c.
︙ | ︙ | |||
74 75 76 77 78 79 80 | NULL, /* Get OS handle from the channel. NULL'able */ ReflectClose, /* No close2 support. NULL'able */ ReflectBlock, /* Set blocking/nonblocking. NULL'able */ NULL, /* Flush channel. Not used by core. NULL'able */ NULL, /* Handle events. NULL'able */ ReflectSeekWide, /* Move access point (64 bit). NULL'able */ #if TCL_THREADS | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | NULL, /* Get OS handle from the channel. NULL'able */ ReflectClose, /* No close2 support. NULL'able */ ReflectBlock, /* Set blocking/nonblocking. NULL'able */ NULL, /* Flush channel. Not used by core. NULL'able */ NULL, /* Handle events. NULL'able */ ReflectSeekWide, /* Move access point (64 bit). NULL'able */ #if TCL_THREADS ReflectThread, /* thread action, tracking owner */ #else NULL, /* thread action */ #endif ReflectTruncate /* Truncate. NULL'able */ }; /* |
︙ | ︙ | |||
96 97 98 99 100 101 102 | * Tcl level part of the channel. NULL here * signals the channel is dead because the * interpreter/thread containing its Tcl * command is gone. */ #if TCL_THREADS Tcl_ThreadId thread; /* Thread the 'interp' belongs to. == Handler thread */ | | | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | * Tcl level part of the channel. NULL here * signals the channel is dead because the * interpreter/thread containing its Tcl * command is gone. */ #if TCL_THREADS Tcl_ThreadId thread; /* Thread the 'interp' belongs to. == Handler thread */ Tcl_ThreadId owner; /* Thread owning the structure. == Channel thread */ #endif Tcl_Obj *cmd; /* Callback command prefix */ Tcl_Obj *methods; /* Methods to append to command prefix */ Tcl_Obj *name; /* Name of the channel as created */ int mode; /* Mask of R/W mode */ int interest; /* Mask of events the channel is interested * in. */ int dead; /* Boolean signal that some operations * should no longer be attempted. */ Tcl_TimerToken readTimer; /* A token for the timer that is scheduled in order to call Tcl_NotifyChannel when the channel is readable */ Tcl_TimerToken writeTimer; /* A token for the timer that is scheduled in order to call Tcl_NotifyChannel when the channel is writable */ /* * Note regarding the usage of timers. * * Most channel implementations need a timer in the C level to ensure that * data in buffers is flushed out through the generation of fake file * events. |
︙ | ︙ | |||
609 610 611 612 613 614 615 | * Verify the result. * - List, of method names. Convert to mask. * Check for non-optionals through the mask. * Compare open mode against optional r/w. */ if (TclListObjGetElements(NULL, resObj, &listc, &listv) != TCL_OK) { | | | | | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | * Verify the result. * - List, of method names. Convert to mask. * Check for non-optionals through the mask. * Compare open mode against optional r/w. */ if (TclListObjGetElements(NULL, resObj, &listc, &listv) != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "chan handler \"%s initialize\" returned non-list: %s", TclGetString(cmdObj), TclGetString(resObj))); Tcl_DecrRefCount(resObj); goto error; } methods = 0; while (listc > 0) { if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames, |
︙ | ︙ | |||
635 636 637 638 639 640 641 | methods |= FLAG(methIndex); listc--; } Tcl_DecrRefCount(resObj); if ((REQUIRED_METHODS & methods) != REQUIRED_METHODS) { | | | | | | | | | | | | | | | | | 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | methods |= FLAG(methIndex); listc--; } Tcl_DecrRefCount(resObj); if ((REQUIRED_METHODS & methods) != REQUIRED_METHODS) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "chan handler \"%s\" does not support all required methods", TclGetString(cmdObj))); goto error; } if ((mode & TCL_READABLE) && !HAS(methods, METH_READ)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "chan handler \"%s\" lacks a \"read\" method", TclGetString(cmdObj))); goto error; } if ((mode & TCL_WRITABLE) && !HAS(methods, METH_WRITE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "chan handler \"%s\" lacks a \"write\" method", TclGetString(cmdObj))); goto error; } if (!IMPLIES(HAS(methods, METH_CGET), HAS(methods, METH_CGETALL))) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "chan handler \"%s\" supports \"cget\" but not \"cgetall\"", TclGetString(cmdObj))); goto error; } if (!IMPLIES(HAS(methods, METH_CGETALL), HAS(methods, METH_CGET))) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "chan handler \"%s\" supports \"cgetall\" but not \"cget\"", TclGetString(cmdObj))); goto error; } Tcl_ResetResult(interp); /* * Everything is fine now. |
︙ | ︙ | |||
738 739 740 741 742 743 744 | #endif /* * Return handle as result of command. */ Tcl_SetObjResult(interp, | | | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | #endif /* * Return handle as result of command. */ Tcl_SetObjResult(interp, Tcl_NewStringObj(chanPtr->state->channelName, -1)); return TCL_OK; error: Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); Tcl_DecrRefCount(rcPtr->cmd); Tcl_Free(rcPtr); |
︙ | ︙ | |||
810 811 812 813 814 815 816 | * latter ensures that no pending events of this type are run on an * invalid channel. */ ReflectEvent *e = (ReflectEvent *) ev; if ((ev->proc != ReflectEventRun) || ((cd != NULL) && (cd != e->rcPtr))) { | | | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | * latter ensures that no pending events of this type are run on an * invalid channel. */ ReflectEvent *e = (ReflectEvent *) ev; if ((ev->proc != ReflectEventRun) || ((cd != NULL) && (cd != e->rcPtr))) { return 0; } return 1; } #endif int TclChanPostEventObjCmd( |
︙ | ︙ | |||
869 870 871 872 873 874 875 | chanId = TclGetString(objv[CHAN]); rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, chanId); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( | | | 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 | chanId = TclGetString(objv[CHAN]); rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, chanId); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can not find reflected channel named \"%s\"", chanId)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanId, (char *)NULL); return TCL_ERROR; } /* * Note that the search above subsumes several of the older checks, * namely: |
︙ | ︙ | |||
933 934 935 936 937 938 939 | /* * Check that the channel is actually interested in the provided events. */ if (events & ~rcPtr->interest) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( | | | | 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 | /* * Check that the channel is actually interested in the provided events. */ if (events & ~rcPtr->interest) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "tried to post events channel \"%s\" is not interested in", chanId)); return TCL_ERROR; } /* * We have the channel and the events to post. */ |
︙ | ︙ | |||
959 960 961 962 963 964 965 | if (rcPtr->writeTimer == NULL) { rcPtr->writeTimer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, TimerRunWrite, rcPtr); } } #if TCL_THREADS } else { | | | | | | | | | | | | | | | | | | | | | | | | | | | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 | if (rcPtr->writeTimer == NULL) { rcPtr->writeTimer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, TimerRunWrite, rcPtr); } } #if TCL_THREADS } else { ReflectEvent *ev = (ReflectEvent *)Tcl_Alloc(sizeof(ReflectEvent)); ev->header.proc = ReflectEventRun; ev->events = events; ev->rcPtr = rcPtr; /* * We are not preserving the structure here. When the channel is * closed any pending events are deleted, see ReflectClose(), and * ReflectEventDelete(). Trying to preserve and later release when the * event is run may generate a situation where the channel structure * is deleted but not our structure, crashing in * FreeReflectedChannel(). * * Force creation of the RCM, for proper cleanup on thread teardown. * The teardown of unprocessed events is currently coupled to the * thread reflected channel map */ (void) GetThreadReflectedChannelMap(); /* * XXX Race condition !! * XXX The destination thread may not exist anymore already. * XXX (Delayed postevent executed after channel got removed). * XXX Can we detect this ? (check the validity of the owner threadid ?) * XXX Actually, in that case the channel should be dead also ! */ Tcl_ThreadQueueEvent(rcPtr->owner, (Tcl_Event *) ev, TCL_QUEUE_TAIL|TCL_QUEUE_ALERT_IF_EMPTY); } #endif /* * Squash interp results left by the event script. */ |
︙ | ︙ | |||
1203 1204 1205 1206 1207 1208 1209 | #if TCL_THREADS if (rcPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p); result = p.base.code; | | | | | | 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 | #if TCL_THREADS if (rcPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p); result = p.base.code; /* * Now squash the pending reflection events for this channel. */ Tcl_DeleteEvents(ReflectEventDelete, rcPtr); if (result != TCL_OK) { FreeReceivedError(&p); } } #endif |
︙ | ︙ | |||
1241 1242 1243 1244 1245 1246 1247 | #if TCL_THREADS if (rcPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p); result = p.base.code; | | | | | | 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 | #if TCL_THREADS if (rcPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p); result = p.base.code; /* * Now squash the pending reflection events for this channel. */ Tcl_DeleteEvents(ReflectEventDelete, rcPtr); if (result != TCL_OK) { PassReceivedErrorInterp(interp, &p); } } else { #endif result = InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj); |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | Tcl_IncrRefCount(toReadObj); if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK) { int code = ErrnoReturn(rcPtr, resObj); if (code < 0) { *errorCodePtr = -code; | | | | 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 | Tcl_IncrRefCount(toReadObj); if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK) { int code = ErrnoReturn(rcPtr, resObj); if (code < 0) { *errorCodePtr = -code; goto error; } Tcl_SetChannelError(rcPtr->chan, resObj); goto invalid; } bytev = Tcl_GetBytesFromObj(NULL, resObj, &bytec); if (bytev == NULL) { SetChannelErrorStr(rcPtr->chan, msg_read_nonbyte); goto invalid; |
︙ | ︙ | |||
1464 1465 1466 1467 1468 1469 1470 | if (p.base.code < 0) { /* * No error message, this is an errno signal. */ *errorCodePtr = -p.base.code; } else { | | | | | 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 | if (p.base.code < 0) { /* * No error message, this is an errno signal. */ *errorCodePtr = -p.base.code; } else { PassReceivedError(rcPtr->chan, &p); *errorCodePtr = EINVAL; } p.output.toWrite = -1; } else { *errorCodePtr = EOK; } return p.output.toWrite; } |
︙ | ︙ | |||
1490 1491 1492 1493 1494 1495 1496 | Tcl_IncrRefCount(bufObj); if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) { int code = ErrnoReturn(rcPtr, resObj); if (code < 0) { *errorCodePtr = -code; | | | | | | | | 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | Tcl_IncrRefCount(bufObj); if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) { int code = ErrnoReturn(rcPtr, resObj); if (code < 0) { *errorCodePtr = -code; goto error; } Tcl_SetChannelError(rcPtr->chan, resObj); goto invalid; } if (Tcl_InterpDeleted(rcPtr->interp)) { /* * The interp was destroyed during InvokeTclMethod(). */ SetChannelErrorStr(rcPtr->chan, msg_send_dstlost); goto invalid; } if (Tcl_GetIntFromObj(rcPtr->interp, resObj, &written) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp)); goto invalid; } if ((written == 0) && (toWrite > 0)) { /* * The handler claims to have written nothing of what it was given. * That is bad. */ SetChannelErrorStr(rcPtr->chan, msg_write_nothing); goto invalid; } if (toWrite < written) { /* * The handler claims to have written more than it was given. That is * bad. Note that the I/O core would crash if we were to return this * information, trying to write -nnn bytes in the next iteration. */ SetChannelErrorStr(rcPtr->chan, msg_write_toomuch); goto invalid; } *errorCodePtr = EOK; stop: Tcl_DecrRefCount(bufObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ Tcl_Release(rcPtr->interp); |
︙ | ︙ | |||
1603 1604 1605 1606 1607 1608 1609 | /* ASSERT: rcPtr->method & FLAG(METH_SEEK) */ Tcl_Preserve(rcPtr); TclNewIntObj(offObj, offset); baseObj = Tcl_NewStringObj( | | | | | | | 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 | /* ASSERT: rcPtr->method & FLAG(METH_SEEK) */ Tcl_Preserve(rcPtr); TclNewIntObj(offObj, offset); baseObj = Tcl_NewStringObj( (seekMode == SEEK_SET) ? "start" : (seekMode == SEEK_CUR) ? "current" : "end", -1); Tcl_IncrRefCount(offObj); Tcl_IncrRefCount(baseObj); if (InvokeTclMethod(rcPtr, METH_SEEK, offObj, baseObj, &resObj)!=TCL_OK) { Tcl_SetChannelError(rcPtr->chan, resObj); goto invalid; } if (TclGetWideIntFromObj(rcPtr->interp, resObj, &newLoc) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp)); goto invalid; } if (newLoc < 0) { SetChannelErrorStr(rcPtr->chan, msg_seek_beforestart); goto invalid; } *errorCodePtr = EOK; stop: Tcl_DecrRefCount(offObj); Tcl_DecrRefCount(baseObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ |
︙ | ︙ | |||
1801 1802 1803 1804 1805 1806 1807 | void *clientData, int action) { ReflectedChannel *rcPtr = (ReflectedChannel *)clientData; switch (action) { case TCL_CHANNEL_THREAD_INSERT: | | | | | | | | 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 | void *clientData, int action) { ReflectedChannel *rcPtr = (ReflectedChannel *)clientData; switch (action) { case TCL_CHANNEL_THREAD_INSERT: rcPtr->owner = Tcl_GetCurrentThread(); break; case TCL_CHANNEL_THREAD_REMOVE: rcPtr->owner = NULL; break; default: Tcl_Panic("Unknown thread action code."); break; } } #endif /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1967 1968 1969 1970 1971 1972 1973 | } else { /* * Retrieve the value of one option. */ method = METH_CGET; optionObj = Tcl_NewStringObj(optionName, -1); | | | | | | | | | 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 | } else { /* * Retrieve the value of one option. */ method = METH_CGET; optionObj = Tcl_NewStringObj(optionName, -1); Tcl_IncrRefCount(optionObj); } Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, method, optionObj, NULL, &resObj)!=TCL_OK) { UnmarshallErrorResult(interp, resObj); goto error; } /* * The result has to go into the 'dsPtr' for propagation to the caller of * the driver. */ if (optionObj != NULL) { TclDStringAppendObj(dsPtr, resObj); goto ok; } /* * Extract the list and append each item as element. */ /* * NOTE (4): If we extract the string rep we can assume a properly quoted * string. Together with a separating space this way of simply appending * the whole string rep might be faster. It also doesn't check if the * result is a valid list. Nor that the list has an even number elements. */ if (TclListObjGetElements(interp, resObj, &listc, &listv) != TCL_OK) { goto error; } if ((listc % 2) == 1) { /* * Odd number of elements is wrong. */ Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Expected list with even number of " "elements, got %" TCL_SIZE_MODIFIER "d element%s instead", listc, (listc == 1 ? "" : "s"))); goto error; } else { Tcl_Size len; const char *str = TclGetStringFromObj(resObj, &len); if (len) { TclDStringAppendLiteral(dsPtr, " "); Tcl_DStringAppend(dsPtr, str, len); } goto ok; } ok: result = TCL_OK; stop: if (optionObj) { Tcl_DecrRefCount(optionObj); } Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ Tcl_Release(rcPtr); return result; error: result = TCL_ERROR; goto stop; |
︙ | ︙ | |||
2382 2383 2384 2385 2386 2387 2388 | if (resultObjPtr != NULL) { resObj = Tcl_NewStringObj(msg_dstlost,-1); *resultObjPtr = resObj; Tcl_IncrRefCount(resObj); } | | | | | | 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 | if (resultObjPtr != NULL) { resObj = Tcl_NewStringObj(msg_dstlost,-1); *resultObjPtr = resObj; Tcl_IncrRefCount(resObj); } /* * Not touching argOneObj, argTwoObj, they have not been used. * See the contract as well. */ return TCL_ERROR; } /* * Insert method into the callback command, after the command prefix, * before the channel id. |
︙ | ︙ | |||
2681 2682 2683 2684 2685 2686 2687 | continue; } /* * The receiver for the event exited, before processing the event. We * detach the result now, wake the originator up and signal failure. | | | | | | | 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 | continue; } /* * The receiver for the event exited, before processing the event. We * detach the result now, wake the originator up and signal failure. * * Attention: Results may have been detached already, by either the * receiver, or this thread, as part of other parts in the thread * teardown. Such results are ignored. See ticket [b47b176adf] for the * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; /* * Basic crash safety until this routine can get revised [3411310] */ |
︙ | ︙ | |||
2834 2835 2836 2837 2838 2839 2840 | continue; } /* * The receiver for the event exited, before processing the event. We * detach the result now, wake the originator up and signal failure. | | | | | | | 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 | continue; } /* * The receiver for the event exited, before processing the event. We * detach the result now, wake the originator up and signal failure. * * Attention: Results may have been detached already, by either the * receiver, or this thread, as part of other parts in the thread * teardown. Such results are ignored. See ticket [b47b176adf] for the * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; /* * Basic crash safety until this routine can get revised [3411310] */ |
︙ | ︙ | |||
3047 3048 3049 3050 3051 3052 3053 | ForwardingEvent *evPtr = (ForwardingEvent *) evGPtr; ForwardingResult *resultPtr = evPtr->resultPtr; ReflectedChannel *rcPtr = evPtr->rcPtr; Tcl_Interp *interp = rcPtr->interp; ForwardParam *paramPtr = evPtr->param; Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */ ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in | | | 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 | ForwardingEvent *evPtr = (ForwardingEvent *) evGPtr; ForwardingResult *resultPtr = evPtr->resultPtr; ReflectedChannel *rcPtr = evPtr->rcPtr; Tcl_Interp *interp = rcPtr->interp; ForwardParam *paramPtr = evPtr->param; Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */ ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in * this interp. */ Tcl_HashEntry *hPtr; /* Entry in the above map */ /* * Ignore the event if no one is waiting for its result anymore. */ if (!resultPtr) { |
︙ | ︙ | |||
3090 3091 3092 3093 3094 3095 3096 | * We remove the channel from both interpreter and thread maps before * releasing the memory, to prevent future accesses (like by * 'postevent') from finding and dereferencing a dangling pointer. */ rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, | | | | 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 | * We remove the channel from both interpreter and thread maps before * releasing the memory, to prevent future accesses (like by * 'postevent') from finding and dereferencing a dangling pointer. */ rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); Tcl_DeleteHashEntry(hPtr); rcmPtr = GetThreadReflectedChannelMap(); hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); Tcl_DeleteHashEntry(hPtr); MarkDead(rcPtr); break; } case ForwardedInput: { Tcl_Obj *toReadObj; |
︙ | ︙ | |||
3140 3141 3142 3143 3144 3145 3146 | } else { if (bytec > 0) { memcpy(paramPtr->input.buf, bytev, bytec); } paramPtr->input.toRead = bytec; } } | | | | | | | 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 | } else { if (bytec > 0) { memcpy(paramPtr->input.buf, bytev, bytec); } paramPtr->input.toRead = bytec; } } Tcl_Release(rcPtr); Tcl_DecrRefCount(toReadObj); break; } case ForwardedOutput: { Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *) paramPtr->output.buf, paramPtr->output.toWrite); Tcl_IncrRefCount(bufObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) { int code = ErrnoReturn(rcPtr, resObj); if (code < 0) { paramPtr->base.code = code; } else { ForwardSetObjError(paramPtr, resObj); |
︙ | ︙ | |||
3179 3180 3181 3182 3183 3184 3185 | } else if (written==0 || paramPtr->output.toWrite<written) { ForwardSetStaticError(paramPtr, msg_write_toomuch); paramPtr->output.toWrite = -1; } else { paramPtr->output.toWrite = written; } } | | | | 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 | } else if (written==0 || paramPtr->output.toWrite<written) { ForwardSetStaticError(paramPtr, msg_write_toomuch); paramPtr->output.toWrite = -1; } else { paramPtr->output.toWrite = written; } } Tcl_Release(rcPtr); Tcl_DecrRefCount(bufObj); break; } case ForwardedSeek: { Tcl_Obj *offObj; Tcl_Obj *baseObj; |
︙ | ︙ | |||
3222 3223 3224 3225 3226 3227 3228 | } else { Tcl_DecrRefCount(resObj); resObj = MarshallError(interp); ForwardSetObjError(paramPtr, resObj); paramPtr->seek.offset = -1; } } | | | | | | | | | | | | | | | | | | | | | | | | | | 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 | } else { Tcl_DecrRefCount(resObj); resObj = MarshallError(interp); ForwardSetObjError(paramPtr, resObj); paramPtr->seek.offset = -1; } } Tcl_Release(rcPtr); Tcl_DecrRefCount(offObj); Tcl_DecrRefCount(baseObj); break; } case ForwardedWatch: { Tcl_Obj *maskObj = DecodeEventMask(paramPtr->watch.mask); /* assert maskObj.refCount == 1 */ Tcl_Preserve(rcPtr); rcPtr->interest = paramPtr->watch.mask; (void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL); Tcl_DecrRefCount(maskObj); Tcl_Release(rcPtr); break; } case ForwardedBlock: { Tcl_Obj *blockObj = Tcl_NewBooleanObj(!paramPtr->block.nonblocking); Tcl_IncrRefCount(blockObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, METH_BLOCKING, blockObj, NULL, &resObj) != TCL_OK) { ForwardSetObjError(paramPtr, resObj); } Tcl_Release(rcPtr); Tcl_DecrRefCount(blockObj); break; } case ForwardedSetOpt: { Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->setOpt.name, -1); Tcl_Obj *valueObj = Tcl_NewStringObj(paramPtr->setOpt.value, -1); Tcl_IncrRefCount(optionObj); Tcl_IncrRefCount(valueObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, METH_CONFIGURE, optionObj, valueObj, &resObj) != TCL_OK) { ForwardSetObjError(paramPtr, resObj); } Tcl_Release(rcPtr); Tcl_DecrRefCount(optionObj); Tcl_DecrRefCount(valueObj); break; } case ForwardedGetOpt: { /* * Retrieve the value of one option. */ Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->getOpt.name, -1); Tcl_IncrRefCount(optionObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, METH_CGET, optionObj, NULL, &resObj)!=TCL_OK){ ForwardSetObjError(paramPtr, resObj); } else { TclDStringAppendObj(paramPtr->getOpt.value, resObj); } Tcl_Release(rcPtr); Tcl_DecrRefCount(optionObj); break; } case ForwardedGetOptAll: /* * Retrieve all options. */ Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, METH_CGETALL, NULL, NULL, &resObj) != TCL_OK){ ForwardSetObjError(paramPtr, resObj); } else { /* * Extract list, validate that it is a list, and #elements. See * NOTE (4) as well. */ Tcl_Size listc; Tcl_Obj **listv; if (TclListObjGetElements(interp, resObj, &listc, &listv) != TCL_OK) { Tcl_DecrRefCount(resObj); resObj = MarshallError(interp); ForwardSetObjError(paramPtr, resObj); } else if ((listc % 2) == 1) { /* * Odd number of elements is wrong. [x]. */ |
︙ | ︙ | |||
3333 3334 3335 3336 3337 3338 3339 | if (len) { TclDStringAppendLiteral(paramPtr->getOpt.value, " "); Tcl_DStringAppend(paramPtr->getOpt.value, str, len); } } } | | | 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 | if (len) { TclDStringAppendLiteral(paramPtr->getOpt.value, " "); Tcl_DStringAppend(paramPtr->getOpt.value, str, len); } } } Tcl_Release(rcPtr); break; case ForwardedTruncate: { Tcl_Obj *lenObj = Tcl_NewWideIntObj(paramPtr->truncate.length); Tcl_IncrRefCount(lenObj); Tcl_Preserve(rcPtr); |
︙ | ︙ |