Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | improvements regarding [9ba84a8a76] |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5362b4849e8f86731466deda1ea8d3d8 |
User & Date: | chw 2019-11-08 22:48:44.544 |
References
2019-11-08
| ||
23:04 | improvements regarding [5362b4849e] check-in: 56ed33b76a user: chw tags: trunk | |
Context
2019-11-08
| ||
23:04 | improvements regarding [5362b4849e] check-in: 56ed33b76a user: chw tags: trunk | |
22:48 | improvements regarding [9ba84a8a76] check-in: 5362b4849e user: chw tags: trunk | |
09:34 | more tcl upstream changes check-in: d330ab7f7d user: chw tags: trunk | |
Changes
Changes to jni/tcl/unix/tclUnixSock.c.
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | */ typedef struct TcpState TcpState; typedef struct TcpFdList { TcpState *statePtr; int fd; struct TcpFdList *next; } TcpFdList; struct TcpState { Tcl_Channel channel; /* Channel associated with this file. */ TcpFdList fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined | > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | */ typedef struct TcpState TcpState; typedef struct TcpFdList { TcpState *statePtr; int fd; int spareFd; struct TcpFdList *next; } TcpFdList; struct TcpState { Tcl_Channel channel; /* Channel associated with this file. */ TcpFdList fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined |
︙ | ︙ | |||
608 609 610 611 612 613 614 615 616 617 618 619 620 621 | */ for (fds = &statePtr->fds; fds != NULL; fds = fds->next) { if (fds->fd < 0) { continue; } Tcl_DeleteFileHandler(fds->fd); if (close(fds->fd) < 0) { errorCode = errno; } } fds = statePtr->fds.next; while (fds != NULL) { | > > > | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | */ for (fds = &statePtr->fds; fds != NULL; fds = fds->next) { if (fds->fd < 0) { continue; } Tcl_DeleteFileHandler(fds->fd); if (fds->spareFd != -1) { close(fds->spareFd); } if (close(fds->fd) < 0) { errorCode = errno; } } fds = statePtr->fds.next; while (fds != NULL) { |
︙ | ︙ | |||
1295 1296 1297 1298 1299 1300 1301 | TclUnixSetBlockingMode(statePtr->fds.fd, statePtr->cachedBlocking); if (error != 0) { SET_BITS(statePtr->flags, TCP_ASYNC_FAILED); } /* | | | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 | TclUnixSetBlockingMode(statePtr->fds.fd, statePtr->cachedBlocking); if (error != 0) { SET_BITS(statePtr->flags, TCP_ASYNC_FAILED); } /* * We need to forward the writable event that brought us here, because * upon reading of getsockopt(SO_ERROR), at least some OSes clear the * writable state from the socket, and so a subsequent select() on * behalf of a script level [fileevent] would not fire. It doesn't * hurt that this is also called in the successful case and will save * the event mechanism one roundtrip through select(). */ |
︙ | ︙ | |||
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 | statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->flags = async ? TCP_ASYNC_CONNECT : 0; statePtr->cachedBlocking = TCL_MODE_BLOCKING; statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; statePtr->fds.fd = -1; /* * Create a new client socket and wrap it in a channel. */ if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); | > | 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 | statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->flags = async ? TCP_ASYNC_CONNECT : 0; statePtr->cachedBlocking = TCL_MODE_BLOCKING; statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; statePtr->fds.fd = -1; statePtr->fds.spareFd = -1; /* * Create a new client socket and wrap it in a channel. */ if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); |
︙ | ︙ | |||
1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 | { TcpState *statePtr; char channelName[SOCK_CHAN_LENGTH]; statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->fds.fd = PTR2INT(sock); statePtr->flags = 0; sprintf(channelName, SOCK_TEMPLATE, (long)statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, mode); if (Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", | > | 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 | { TcpState *statePtr; char channelName[SOCK_CHAN_LENGTH]; statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->fds.fd = PTR2INT(sock); statePtr->fds.spareFd = -1; statePtr->flags = 0; sprintf(channelName, SOCK_TEMPLATE, (long)statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, mode); if (Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", |
︙ | ︙ | |||
1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 | newfds = &statePtr->fds; } else { newfds = ckalloc(sizeof(TcpFdList)); memset(newfds, (int) 0, sizeof(TcpFdList)); fds->next = newfds; } newfds->fd = sock; newfds->statePtr = statePtr; fds = newfds; /* * Set up the callback mechanism for accepting connections from new * clients. */ | > | 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 | newfds = &statePtr->fds; } else { newfds = ckalloc(sizeof(TcpFdList)); memset(newfds, (int) 0, sizeof(TcpFdList)); fds->next = newfds; } newfds->fd = sock; newfds->spareFd = dup(sock); newfds->statePtr = statePtr; fds = newfds; /* * Set up the callback mechanism for accepting connections from new * clients. */ |
︙ | ︙ | |||
1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 | socklen_t len; /* For accept interface */ char channelName[SOCK_CHAN_LENGTH]; char host[NI_MAXHOST], port[NI_MAXSERV]; len = sizeof(addr); newsock = accept(fds->fd, &addr.sa, &len); if (newsock < 0) { return; } /* * Ticket [c6897e6e6a]. */ | > > > > > > > > > > > > > > > > > > > > > > > > | 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 | socklen_t len; /* For accept interface */ char channelName[SOCK_CHAN_LENGTH]; char host[NI_MAXHOST], port[NI_MAXSERV]; len = sizeof(addr); newsock = accept(fds->fd, &addr.sa, &len); if (newsock < 0) { /* * Last resort: try to cleanup the listen backlog. If that * fails, a busy event loop is the most likely outcome. * Due to process semantic of the file descriptor table * this strategy is inherently not threadsafe. It could * be remedied if there was a system call which combines * accept() with dup() using a spare pre-allocated file * descriptor. Otherwise, ALL system calls producing a * new file descriptor would require to be mutexed in order * to guarantee availability of that spare file descriptor. */ if (errno == EMFILE || errno == ENFILE) { if (fds->spareFd != -1) { close(fds->spareFd); len = sizeof(addr); fds->spareFd = accept(fds->fd, &addr.sa, &len); if (fds->spareFd >= 0) { close(fds->spareFd); fds->spareFd = dup(fds->fd); } } } return; } /* * Ticket [c6897e6e6a]. */ |
︙ | ︙ | |||
1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 | (void) fcntl(newsock, F_SETFD, FD_CLOEXEC); newSockState = ckalloc(sizeof(TcpState)); memset(newSockState, 0, sizeof(TcpState)); newSockState->flags = 0; newSockState->fds.fd = newsock; sprintf(channelName, SOCK_TEMPLATE, (long) newSockState); newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName, newSockState, TCL_READABLE | TCL_WRITABLE); Tcl_SetChannelOption(NULL, newSockState->channel, "-translation", "auto crlf"); | > | 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 | (void) fcntl(newsock, F_SETFD, FD_CLOEXEC); newSockState = ckalloc(sizeof(TcpState)); memset(newSockState, 0, sizeof(TcpState)); newSockState->flags = 0; newSockState->fds.fd = newsock; newSockState->fds.spareFd = -1; sprintf(channelName, SOCK_TEMPLATE, (long) newSockState); newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName, newSockState, TCL_READABLE | TCL_WRITABLE); Tcl_SetChannelOption(NULL, newSockState->channel, "-translation", "auto crlf"); |
︙ | ︙ |