Diff
Not logged in

Differences From Artifact [bfdb6915c2]:

To Artifact [c82abbc611]:


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
TcpCloseProc(
    ClientData instanceData,	/* The socket to close. */
    Tcl_Interp *interp)		/* Unused. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    /* TIP #218 */
    int errorCode = 0;
    /* ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); */

    /*
     * Check that WinSock is initialized; do not call it if not, to prevent
     * system crashes. This can happen at exit time if the exit handler for
     * WinSock ran before other exit handlers that want to use sockets.
     */

    if (SocketsEnabled()) {
	/*
	 * Clean up the OS socket handle. The default Windows setting for a
	 * socket is SO_DONTLINGER, which does a graceful shutdown in the
	 * background.
	 */

	if (closesocket(infoPtr->socket) == SOCKET_ERROR) {
	    TclWinConvertWSAError((DWORD) WSAGetLastError());
	    errorCode = Tcl_GetErrno();
	}
    }


















    /*
     * TIP #218. Removed the code removing the structure from the global
     * socket list. This is now done by the thread action callbacks, and only
     * there. This happens before this code is called. We can free without
     * fear of damaging the list.
     */







|



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
TcpCloseProc(
    ClientData instanceData,	/* The socket to close. */
    Tcl_Interp *interp)		/* Unused. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    /* TIP #218 */
    int errorCode = 0;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Check that WinSock is initialized; do not call it if not, to prevent
     * system crashes. This can happen at exit time if the exit handler for
     * WinSock ran before other exit handlers that want to use sockets.
     */

    if (SocketsEnabled()) {
	/*
	 * Clean up the OS socket handle. The default Windows setting for a
	 * socket is SO_DONTLINGER, which does a graceful shutdown in the
	 * background.
	 */

	if (closesocket(infoPtr->socket) == SOCKET_ERROR) {
	    TclWinConvertWSAError((DWORD) WSAGetLastError());
	    errorCode = Tcl_GetErrno();
	}
    }

    /*
     * Clear an eventual tsd info list pointer.
     * This may be called, if an async socket connect fails or is closed
     * between connect and thread action callback.
     */
    if (tsdPtr->pendingSocketInfo != NULL
	    && tsdPtr->pendingSocketInfo == infoPtr) {

	/* get infoPtr lock, because this concerns the notifier thread */
	WaitForSingleObject(tsdPtr->socketListLock, INFINITE);

	tsdPtr->pendingSocketInfo = NULL;

	/* Free list lock */
	SetEvent(tsdPtr->socketListLock);
    }

    /*
     * TIP #218. Removed the code removing the structure from the global
     * socket list. This is now done by the thread action callbacks, and only
     * there. This happens before this code is called. We can free without
     * fear of damaging the list.
     */
1047
1048
1049
1050
1051
1052
1053


1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072



1073
1074
1075
1076
1077
1078
1079
	    /* get infoPtr lock */
	    WaitForSingleObject(tsdPtr->socketListLock, INFINITE);

	    /*
	     * Buffer new infoPtr in the tsd memory as long as it is not in
	     * the info list. This allows the event procedure to process the
	     * event.


	     */

	    tsdPtr->pendingSocketInfo = infoPtr;

	    /*
	     * Set connect mask to connect events
	     * This is activated by a SOCKET_SELECT message to the notifier
	     * thread.
	     */

	    infoPtr->selectEvents |= FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE;
	    infoPtr->flags |= SOCKET_ASYNC_CONNECT;
	    
	    /*
	     * Free list lock
	     */
	    SetEvent(tsdPtr->socketListLock);


	    /* activate accept notification and put in async mode */



	    ioctlsocket(sock, (long) FIONBIO, &flag);
	    SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT,
	            (LPARAM) infoPtr);

	}

	/*







>
>


















>
|
>
>
>







1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
	    /* get infoPtr lock */
	    WaitForSingleObject(tsdPtr->socketListLock, INFINITE);

	    /*
	     * Buffer new infoPtr in the tsd memory as long as it is not in
	     * the info list. This allows the event procedure to process the
	     * event.
	     * Bugfig for 336441ed59 to not ignore notifications until the
	     * infoPtr is in the list..
	     */

	    tsdPtr->pendingSocketInfo = infoPtr;

	    /*
	     * Set connect mask to connect events
	     * This is activated by a SOCKET_SELECT message to the notifier
	     * thread.
	     */

	    infoPtr->selectEvents |= FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE;
	    infoPtr->flags |= SOCKET_ASYNC_CONNECT;
	    
	    /*
	     * Free list lock
	     */
	    SetEvent(tsdPtr->socketListLock);

	    /*
	     * Activate accept notification and put in async mode
	     * Bug 336441ed59: activate notification before connect
	     * so we do not miss a notification of a fialed connect.
	     */
	    ioctlsocket(sock, (long) FIONBIO, &flag);
	    SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT,
	            (LPARAM) infoPtr);

	}

	/*
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132



1133
1134
1135
1136
1137
1138
1139

  error:
    TclWinConvertWSAError((DWORD) WSAGetLastError());
    if (interp != NULL) {
	Tcl_AppendResult(interp, "couldn't open socket: ",
		Tcl_PosixError(interp), NULL);
    }
    /*
     * Clear the tsd socket list pointer if we did not wait for
     * the FD_CONNECT asyncroneously
     */
    tsdPtr->pendingSocketInfo = NULL;
    if (infoPtr != NULL) {
	/*
	 * Free the allocated socket info structure and close the socket
	 */
	TcpCloseProc(infoPtr, interp);
    } else if (sock != INVALID_SOCKET) {



	closesocket(sock);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------







<
<
<
<
<






>
>
>







1138
1139
1140
1141
1142
1143
1144





1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160

  error:
    TclWinConvertWSAError((DWORD) WSAGetLastError());
    if (interp != NULL) {
	Tcl_AppendResult(interp, "couldn't open socket: ",
		Tcl_PosixError(interp), NULL);
    }





    if (infoPtr != NULL) {
	/*
	 * Free the allocated socket info structure and close the socket
	 */
	TcpCloseProc(infoPtr, interp);
    } else if (sock != INVALID_SOCKET) {
	/*
	 * No socket structure jet - just close
	 */
	closesocket(sock);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------