Named pipe using IOCP not working on Windows 10 - windows

I have two Win32 console processes a) a server process and b) a client process.
The Server Process:
i) It creates a IO completion port by calling CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1).
ii) Spawn a worker thread and waiting to run the worker thread. The worker thread blocks on GetQueuedCompletionStatus() inside a loop. It simply logs the values which are coming on GetQueuedCompletionStatus().
iii) Create a named pipe (inbound)
iv) Associate the pipe with the IOCP
v) Connect the named pipe and waiting until the overlapped operation completed in the case of getting ERROR_IO_PENDING
vi) The server thread blocks (using GetMessage loop) until it detects any termination message which will be generated on pressing a key to terminate the server process.
vii) On getting a termination message it posts a completion packet to the IOCP to terminate the worker thread.
viii) After worker thread termination, it disconnects the named pipe, close the handles of the named pipe and IOCP.
The Client Process:
i) Open the named pipe by calling CreateFile().
ii) After successful connection, It writes a string to the pipe by calling WriteFile() and waiting for 10 seconds.
Problem: When the client opens the pipe by calling CreateFile() the server worker thread deque a completion packet (where bytes transferred=0) and GetQueuedCompletionStatus() is returning success code. But when the client is writing the buffer to the pipe, nothing is coming to the worker thread and it remains in blocked state though WriteFile() is returning success. I think that I am missing something. Please help.

Related

Creating an instance of an object implemented by COM LocalServer freezes

I have created a COM object server exe which implements a COM Object, and calls to CoRegisterClassObject, and then sleeps for a long time (to prevent the process from exiting)
After running it, I have another COM client exe which calls to CoCreateInstance with the CLSID of the object registered previously on CoRegisterClassObject,
CoCreateInstance freezes the thread, but if I close the COM Server process - then CoCreateInstance returns immediately with "Class not registered.".
Do any of you know what's going on?
Thank you.
and then sleeps for a long time (to prevent the process from exiting)
Supposedly, server side object lives in STA, which in turn requires message pump/dispatching on its thread to be in good standing. Freezing the thread by sleeping there you block its operation. Client process waits for communication with server process/apartment and expectedly locks as well.
You need to replace your Sleep call with a message pump loop:
MSG Message;
while(GetMessage(&Message, NULL, WM_NULL, WM_NULL) > 0)
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
A typical process exit prevention is periodic check for amount of outstanding external COM references. If the counter was ever greater than zero, and is zero at the check moment - it's a good time for exiting then.

Windows socket write() is blocked by a read() unexpectedly

(this is an updated repost of a previously asked question, posted with old account which I've lost the credentials for)
I'm writing a client-server program, where the client is C++/winapi and the server is C#/.net.
socket is an AF_INET/ SOCK_STREAM and I'm using Readfile() and WriteFile() for socket IO at client.
the client have a loop where it reads from server (and may block the calling thread [denote t1] , which is fine with me). it also have another thread [denote t2] , that wait on an Event object with a timeout.
if the timeout is reached (and the Event is yet to be singled) the t2 thread, will write (exacly on byte) on the same socket.
The problem I have, is that it seems like the write won't return untill the read on t1 returns (in some legitimate scnerions it will never happen) , as if the socket was not full-duplex.
I've checked it buttom to top, there are no other thread-related comlications. I acctually ran the client from a diffrent machine, and used wireshark to sniff traffic. After the timeout was reached, there was nothing on the wire (no matter how long I wait) , untill I wrote some data from server side (so the read() on t1 returned) - and just right after that, the write() of client is finally transmitted.
As I explained in your earlier question, sockets are full duplex. A read in one thread will not block a write in another thread, and vice versa.

IOCP loop termination may cause memory leaks? How to close IOCP loop gracefully

I have the classic IOCP callback that dequeues i/o pending requests, process them, and deallocate them, in this way:
struct MyIoRequest { OVERLAPPED o; /* ... other params ... */ };
bool is_iocp_active = true;
DWORD WINAPI WorkerProc(LPVOID lpParam)
{
ULONG_PTR dwKey;
DWORD dwTrans;
LPOVERLAPPED io_req;
while(is_iocp_active)
{
GetQueuedCompletionStatus((HANDLE)lpParam, &dwTrans, &dwKey, (LPOVERLAPPED*)&io_req, WSA_INFINITE);
// NOTE, i could use GetQueuedCompletionStatusEx() here ^ and set it in the
// alertable state TRUE, so i can wake up the thread with an ACP request from another thread!
printf("dequeued an i/o request\n");
// [ process i/o request ]
...
// [ destroy request ]
destroy_request(io_req);
}
// [ clean up some stuff ]
return 0;
}
Then, in the code I will have somewhere:
MyIoRequest * io_req = allocate_request(...params...);
ReadFile(..., (OVERLAPPED*)io_req);
and this just works perfectly.
Now my question is: What about I want to immediately close the IOCP queue without causing leaks? (e.g. application must exit)
I mean: if i set is_iocp_active to 'false', the next time GetQueuedCompletionStatus() will dequeue a new i/o request, that will be the last i/o request: it will return, causing thread to exit and when a thread exits all of its pending i/o requests are simply canceled by the system, according to MSDN.
But the structures of type 'MyIoRequest' that I have instanced when calling ReadFile() won't be destroyed at all: the system has canceled pending i/o request, but I have to manually destroy those structures I have
created, or I will leak all pending i/o requests when I stop the loop!
So, how I could do this? Am I wrong to stop the IOCP loop with just setting that variable to false? Note that is would happen even if i use APC requests to stop an alertable thread.
The solution that come to my mind is to add every 'MyIoRequest' structures to a queue/list, and then dequeue them when GetQueuedCompletionStatusEx returns, but shouldn't that make some bottleneck, since the enqueue/dequeue process of such MyIoRequest structures must be interlocked? Maybe I've misunderstood how to use the IOCP loop. Can someone bring some light on this topic?
The way I normally shut down an IOCP thread is to post my own 'shut down now please' completion. That way you can cleanly shut down and process all of the pending completions and then shut the threads down.
The way to do this is to call PostQueuedCompletionStatus() with 0 for num bytes, completion key and pOverlapped. This will mean that the completion key is a unique value (you wont have a valid file or socket with a zero handle/completion key).
Step one is to close the sources of completions, so close or abort your socket connections, close files, etc. Once all of those are closed you can't be generating any more completion packets so you then post your special '0' completion; post one for each thread you have servicing your IOCP. Once the thread gets a '0' completion key it exits.
If you are terminating the app, and there's no overriding reason to not do so, (eg. close DB connections, interprocess shared memory issues), call ExitProcess(0).
Failing that, call CancelIO() for all socket handles and process all the cancelled completions as they come in.
Try ExitProcess() first!

Make parent thread wait till child thread finishes in VC

According to MSDN:
The WaitForSingleObject function can wait for the following objects:
Change notification
Console input
Event
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer
Then we can use WaitForSingleObject to make the parent-thread wait for child ones.
int main()
{
HANDLE h_child_thread = CreateThread(0,0, child, 0,0,0); //create a thread in VC
WaitForSingleObject(h_child_thread, INFINITE); //So, parent-thread will wait
return 0;
}
Question
Is there any other way to make parent-thread wait for child ones in VC or Windows?
I don't quite understand the usage of WaitForSingleObject here, does it mean that the thread's handle will be available when the thread terminates?
You can establish communication between threads in multiple ways and the terminating thread may somehow signal its waiting thread. It could be as simple as writing some special value to a shared memory location that the waiting thread can check. But this won't guarantee that the terminating thread has terminated when the waiting thread sees the special value (ordering/race conditions) or that the terminating thread terminates shortly after that (it can just hang or block on something) and it won't guarantee that the special value gets ever set before the terminating thread actually terminates (the thread can crash). WaitForSingleObject (and its companion WaitForMultipleObjects) is a sure way to know of a thread termination when it occurs. Just use it.
The handle will still be available in the sense that its value won't be gone. But it is practically useless after the thread has terminated, except you need this handle to get the thread exit code. And you still need to close the handle in the end. That is unless you're OK with handle/memory leaks.
for the first queation - yes. The method commonly used here is "Join". the usage is language dependant.
In .NET C++ you can use the Thread's Join method. this is from the msdn:
Thread* newThread = new Thread(new ThreadStart(0, Test::Work));
newThread->Start();
if(newThread->Join(waitTime + waitTime))
{
Console::WriteLine(S"New thread terminated.");
}
else
{
Console::WriteLine(S"Join timed out.");
}
Secondly, the thread is terminated when when you are signaled with "WaitForSingleObject" but the handle is still valid (for a terminated thread). So you still need to explicitly close the handle with CloseHandle.

server using an overlapped named pipe : how to use GetOverlappedResult() with ReadFile()?

I have written a server and a client that are using an overlapped named pipe. My problem is mainly with Readfile() and GetOverlappedResult().
Note that this program is a test code. It will be integrated later in a framework (I'm porting linux code to unix that uses AF_UNIX adress family for socket connections)
I describe the server part. I have 2 threads :
1) the main thread opens an overlapped named pipe, then loop over WaitForMultipleObjects(). WaitForMultipleObjects() waits for 3 events: the 1st one waits for a client to connect. The 2nd allows me to cleanly quit the program. The 3rd is signaled when an operation is pending in ReadFile().
2) The second thread is launched when the client is connected. It loops over ReadFile().
Here is the server code:
http://pastebin.com/5rka7dK7
I mainly used MSDN doc (named pipe server using overlapped I/O, named pipe client), the SDK, and other doc on internet, to write that code. Look in [1] for the client code. The client code needs some love, but for now, I focus on making the server working perfectly.
There are 4 functions in the server code (i forget the function that display error messages):
a) svr_new: it creates the overlapped named pipe and the 3 events, and calls ConnectNamedPipe()
b) svr_del frees all the resources
c) _read_data_cb: the thread that calls ReadFile()
d) the main() function (the main thread), which loops over WaitForMultipleObjects()
My aim is to detect in _read_data_cb() when the client disconnects (ReadFile() fails and GetLastError() returns ERROR_BROKEN_PIPE) and when data comes from the client.
What I don't understand:
Should I call GetOverlappedResult() ?
If yes, where ? When ReadFile() fails and GetLastError() returns ERROR_IO_PENDING (line 50 of the paste) ? When WaitForMultipleObjects() returns (line 303 of the paste, I commented the code there) ? Somewhere else ?
I do a ResetEvent of the event of ReadFile() when WaitForMultipleObjects() returns (line 302 of the paste). Is it the correct place to call it ?
With the code I pasted, here is the result if the client sends these 24 bytes (the ReadFile() buffer is of size 5 bytes. I intentionnaly set that value to test what to do if a client sends some data larger than the ReadFile() buffer)
message : "salut, c'est le client !"
output:
$ ./server.exe
waiting for client...
WaitForMultipleObjects : 0
client connected (1)
WaitForMultipleObjects : 2
* ReadFile : 5
WaitForMultipleObjects : 2
* ReadFile : 5
WaitForMultipleObjects : 2
* ReadFile : 5
WaitForMultipleObjects : 2
* ReadFile : 5
WaitForMultipleObjects : 2
* ReadFile : 4
Note: WaitForMultipleObjects() can be called less than that, it seems random.
So, in my code, I do not call getOverlappedResult(), ReadFile() succeeds (il reads 5*4 + 4 = 24 bytes), but I don't know when the read operation has finished.
Note: I I add a printf() when ReadFile() fails with ERROR_IO_PENDING, that printf() is called indefinitely.
In addition, the client sends 2 messages. The one above, and another one 3seconds later. The 2nd message is never read and ReadFile() fails with the error ERROR_SUCCESS... (so to be precise, ReadFile() returns FALSE and GetLastError() returns ERROR_SUCCESS)
So, I'm completely lost. I have searched hours on Internet, in MSDN, in the SDK code (Server32.c and Client32.c). I still do not know what to do in my specific case.
So, ca someone explain me how to use GetOverlappedResult() (if I have to use it) to know how to check if the read operation finished, and where ? And even, if someone can fix my code :-) I gave the code so that everyone can test it (i find a lot of doc on internet, but it is almost always not precise at all :-/ )
thank you
[1] http://pastebin.com/fbCH2By8
Take a look at I/O Completion Ports. In my opinion it's the most efficient way to receive and handle notifications about overlapped operations in Windows. So basically you will need to use GetQueuedCompletionStatus and GetQueuedCompletionStatusEx in blocking and non-blocking mode when you're ready to process new completion events, instead of calling GetOverlappedResult from time to time. As a matter of fact, you can even get rid of WaitForMultipleObjects completely.
Also, which flavor of Unix are you targeting? In Solaris there's a very similar abstraction. Check out man port_create.
Unfortunately, there's nothing similar in Linux. Signals (including real-time) can be used to some extent as waitable completion objects, but they are not as comprehensive as the ports in Windows and Solaris.

Resources