Imagine the following code which contains a clear runtime error:
PHP Code:
new Handle:MySocket;
OnPluginStart() {
MySocket = SocketCreate(SOCKET_TCP, OnSocketError);
SocketConnect(MySocket, OnSocketConnect, OnSocketReceive, OnSocketDisconnect, "localhost", 12345);
someFunction();
someOtherFunction();
}
someFunction() {
SocketClose(MySocket);
}
someOtherFunction() {
SocketSend(MySocket, "blabla");
}
public OnSocketConnect(...
SocketClose will do the following tasks:
1. terminate operation for the specific socket object
2. remove all queued callbacks
3. call something like InvalidateHandle(Handle_t x)
InvalidateHandle must invalidate the handle instantly to make SocketSend in someOtherFunction() throw an error when ReadHandle fails.
In the next GC run (which shouldn't be too late) OnHandleDestroy frees all resources attached to the specific socket.
The socket extension will report all alive socket handles in IExtensionInterface::OnTraceHandles through ITraceHandler::Trace. All data arguments will be reported in IHandleType::OnTraceHandle with ITraceHandler::MaybeTrace.
I also need a legacy interface for old scripts to process CloseHandle similar to the new CloseSocket.
edit: Note that
MySocket is global and therefore doesn't drop the reference to the handle, but the Handle should be collected after InvalidateHandle anyway.