| ︙ | | |
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
-
+
|
} address;
#ifndef IN6_ARE_ADDR_EQUAL
#define IN6_ARE_ADDR_EQUAL IN6_ADDR_EQUAL
#endif
/*
* This structure describes per-instance state of a tcp based channel.
* This structure describes per-instance state of a tcp-based channel.
*/
typedef struct TcpState TcpState;
typedef struct TcpFdList {
TcpState *statePtr;
SOCKET fd;
|
| ︙ | | |
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
-
+
|
* This error is still a windows error code.
* Access must be protected by semaphore */
struct TcpState *nextPtr; /* The next socket on the per-thread socket
* list. */
};
/*
* These bits may be ORed together into the "flags" field of a TcpState
* These bits may be OR'ed together into the "flags" field of a TcpState
* structure.
*/
#define TCP_NONBLOCKING (1<<0) /* Socket with non-blocking I/O */
#define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */
#define SOCKET_EOF (1<<2) /* A zero read happened on the
* socket. */
|
| ︙ | | |
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
|
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
|
-
-
+
+
|
*
* There are two modes of operation, defined by errorCodePtr:
* * non-NULL: Called by explicite read/write command. Block if socket
* is blocking.
* May return two error codes:
* * EWOULDBLOCK: if connect is still in progress
* * ENOTCONN: if connect failed. This would be the error message
* of a rect or sendto syscall so this is emulated here.
* * Null: Called by a backround operation. Do not block and don't
* of a recv or sendto syscall so this is emulated here.
* * Null: Called by a background operation. Do not block and don't
* return any error code.
*
* Results:
* 0 if the connection has completed, -1 if still in progress or there is
* an error.
*
* Side effects:
|
| ︙ | | |
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
680
|
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
680
|
-
+
-
+
-
+
|
* Consume the connect event.
*/
CLEAR_BITS(statePtr->readyEvents, FD_CONNECT);
/*
* For blocking sockets and foreground processing, disable async
* connect as we continue now synchoneously.
* connect as we continue now synchronously.
*/
if (errorCodePtr != NULL &&
!GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) {
CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
}
/*
* Free list lock.
*/
SetEvent(tsdPtr->socketListLock);
/*
* Continue connect. If switched to synchroneous connect, the
* Continue connect. If switched to synchronous connect, the
* connect is terminated.
*/
result = TcpConnect(NULL, statePtr);
/*
* Restore event service mode.
*/
(void) Tcl_SetServiceMode(oldMode);
/*
* Check for Succesfull connect or async connect restart
* Check for Successful connect or async connect restart
*/
if (result == TCL_OK) {
/*
* Check for async connect restart (not possible for
* foreground blocking operation)
*/
|
| ︙ | | |
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
|
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
|
-
+
|
break;
}
error = WSAGetLastError();
/*
* If an RST comes, then ignore the error and report an EOF just like
* on unix.
* on Unix.
*/
if (error == WSAECONNRESET) {
SET_BITS(statePtr->flags, SOCKET_EOF);
bytesRead = 0;
break;
}
|
| ︙ | | |
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
|
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
|
-
+
|
size_t len = 0;
int reverseDNS = 0;
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"
/*
* Go one step in async connect
*
* If any error is thrown save it as backround error to report eventually
* If any error is thrown save it as background error to report eventually
* below.
*/
if (!GOT_BITS(statePtr->flags, TCP_ASYNC_TEST_MODE)) {
WaitForConnect(statePtr, NULL);
}
|
| ︙ | | |
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
|
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
|
-
+
|
statePtr->addr->ai_addrlen);
error = WSAGetLastError();
Tcl_WinConvertError(error);
if (async_connect && error == WSAEWOULDBLOCK) {
/*
* Asynchroneous connect
* Asynchronous connect
*
* Remember that we jump back behind this next round
*/
SET_BITS(statePtr->flags, TCP_ASYNC_PENDING);
return TCL_OK;
|
| ︙ | | |
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
|
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
|
-
+
|
* Async connect terminated
*/
CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
if (Tcl_GetErrno() == 0) {
/*
* Succesfully connected
* Successfully connected
*
* Set up the select mask for read/write events.
*/
statePtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE;
/*
|
| ︙ | | |
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
|
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
|
-
+
|
* Free list lock.
*/
SetEvent(tsdPtr->socketListLock);
}
/*
* Error message on synchroneous connect
* Error message on synchronous connect
*/
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't open socket: %s", Tcl_PosixError(interp)));
}
return TCL_ERROR;
|
| ︙ | | |
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
|
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
|
-
+
-
+
|
/*
* Get statePtr lock.
*/
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
/*
* Check if event occured.
* Check if event occurred.
*/
event_found = GOT_BITS(statePtr->readyEvents, events);
/*
* Free list lock.
*/
SetEvent(tsdPtr->socketListLock);
/*
* Exit loop if event occured.
* Exit loop if event occurred.
*/
if (event_found) {
break;
}
/*
|
| ︙ | | |
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
|
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
|
-
+
|
* interest in a socket event, and the event has occurred.
*
* Results:
* 0 on success.
*
* Side effects:
* The flags for the given socket are updated to reflect the event that
* occured.
* occurred.
*
*----------------------------------------------------------------------
*/
static LRESULT CALLBACK
SocketProc(
HWND hwnd,
|
| ︙ | | |
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
|
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
|
-
+
|
}
/*
*----------------------------------------------------------------------
*
* FindFDInList --
*
* Return true, if the given file descriptior is contained in the
* Return true, if the given file descriptor is contained in the
* file descriptor list.
*
* Results:
* true if found.
*
* Side effects:
*
|
| ︙ | | |