[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Asynchronous I/O to spawned process

Posted on 2003-10-21
10
Medium Priority
?
1,171 Views
Last Modified: 2013-12-03
Hi!

I want to perform asynchronous I/O on stdout/stdin on a spawned process.
So far i have only been able to do synchronous I/O. I have read that
asynchrounous I/O is possible using named pipes, but i haven't been able
to make it work. Does anyone have a clue?

Some code to illustrate my problem
<-- asyncapp.cpp -->
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

int main(void)
{
      for(int x=10; x--;)
      {
            printf("%d ", x);
            Sleep(1000);
      }
      return 0;
}



<-- redirectedconsole.cpp -->
#define WIN32_LEAN_AND_MEAN
#define BUFSIZE 4096
#include <windows.h>
#include <stdio.h>
#include <conio.h>

HANDLE m_hChildStdoutRd;

DWORD WINAPI readthread(LPVOID lpParameter)
{
      DWORD dwRead;
      TCHAR chBuf[BUFSIZE+1];

      for (;;)
      {
            if(!ReadFile(m_hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) || dwRead==0)
                  break;

            chBuf[dwRead]='\0';
            printf(chBuf);
      }

      return 0;
}

int main(void)
{
      HANDLE hChildStdoutRdTmp, m_hChildStdoutWr, hSaveStdout;
      SECURITY_ATTRIBUTES saAttr;
      PROCESS_INFORMATION piProcInfo;
      STARTUPINFO siStartInfo;
      DWORD id;

      // Set the bInheritHandle flag so pipe handles are inherited.
      saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
      saAttr.bInheritHandle = TRUE;
      saAttr.lpSecurityDescriptor = NULL;

      // Save the handle to the current STDOUT.
      hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

      // Create a pipe for the child process's STDOUT.
      if(!CreatePipe(&hChildStdoutRdTmp, &m_hChildStdoutWr, &saAttr, 0))
            return FALSE;

      // Set a write handle to the pipe to be STDOUT.
      if(!SetStdHandle(STD_OUTPUT_HANDLE, m_hChildStdoutWr))
            return FALSE;

      // Create noninheritable read handle and close the inheritable read handle.
      if(!DuplicateHandle(GetCurrentProcess(), hChildStdoutRdTmp, GetCurrentProcess(), &m_hChildStdoutRd, 0, TRUE, DUPLICATE_SAME_ACCESS))
            return FALSE;

      // Close original handle
      CloseHandle(hChildStdoutRdTmp);

      // Restore saved handle
      if(!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
            return FALSE;

      // Set up STARTUPINFO
      ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
      siStartInfo.cb = sizeof(STARTUPINFO);
      siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
      siStartInfo.wShowWindow = SW_HIDE;
      siStartInfo.hStdInput = NULL;
      siStartInfo.hStdOutput = m_hChildStdoutWr;
      siStartInfo.hStdError = m_hChildStdoutWr;

      // Create child process
      if(!CreateProcess(NULL, "asyncapp.exe", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &siStartInfo, &piProcInfo))
            return FALSE;

      // Create read thread
      if(!CreateThread(NULL, 0, readthread, 0, 0, &id))
            return FALSE;

      getch();
      return TRUE;
}
0
Comment
Question by:oskii
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
10 Comments
 
LVL 8

Expert Comment

by:mxjijo
ID: 9591865

I dont know if I totally understood what u need to achive but..

In general, most of the I/O access could be made asynchronous by setting proper flags during creation time or later, depending up on what u are creating. For example if you specify FILE_FLAG_OVERLAPPED flag, you can perform async operation on that file.

In your case, as far as I know CreatePipe() doesnot support async operations. But, try CreateNamedPipe() with PE_NOWAIT flag. Then you'll be able to do non-blocking IO operations. Take a look at the following links to see more on async IO operations.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/synchronous_and_overlapped_input_and_output.asp

~ J
0
 

Author Comment

by:oskii
ID: 9592403
Instead of create pipe I have tried to create a named pipe with:

OVERLAPPED OverlapObj;
hChildStdoutRdTmp=CreateNamedPipe("\\\\.\\pipe\\apipe", PIPE_ACCESS_INBOUND|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 4096, 4096, 500, NULL);
m_hChildStdoutWr=CreateFile("\\\\.\\pipe\\apipe", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
ZeroMemory(&OverlapObj, sizeof(OverlapObj));
ConnectNamedPipe(hChildStdoutRdTmp, &OverlapObj);

If I then put WaitForSingleObject() in the read thread, it will never return, i suppose something is wrong...
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 9593270

Explain me a little more... how did you do it ?

Did you setup the OVERLAPPED structure properly ?
What id the return value of ReadFile() ??
What hande are you passing to WaitForSingleObject() ?

~ J


0
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 

Author Comment

by:oskii
ID: 9593496
I have not done any setup of the overlapped structure (other than ZeroMemory). I dont really know what i shoud fill it with, this might be the problem.
I passed the m_hChildStdoutRd handle to WaitForSingleObject. ReadFile returns nonzero and sets last error to 997 (Overlapped I/O operation is in progress)

Thank you mxjijo for your interest in this question!
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 9594051

Its not the way Async IO works.

Its fine that u're passing Zero'd OV structure to ConnectPipe().

But you have to prepare another one for ReadFile too, which in your case should not be Zero'd.

As you mentioned, your ReadFile() will return immediately with IN_PROGRESS error. Now, you have to wait for that IO operation to compleate. This could be done as follows

* Prepare an OVERLAPPED structure and pass it to ReadFile() with an Event, created prior to this. System will set that event once the IO operation is compleated. Infact this is the handle that you should pass to your WaitForSingleObject().

   Wait - Not ovet yet. Now, once the Event is triggered, you can assume the io operation is over, but there could be an error. So you should check the status of this operation using GetOverlappedResult(), passing the OV structure and Pipe handle above. Now, you have more clear idea how many bytes has been transferred, what eas the result etc.

   You should read up on the link I gave you before. It explains the typical Async IO operation.

~ J
0
 

Author Comment

by:oskii
ID: 9601152
Thank you for your reply, i have not been able to make overlapped I/O work yet, but i am confused weither overlapped communication really solves the main problem, if you compile and run the asyncapp.cpp (you can probably do it mentaly), you will se that it displays 9 <one sec delay> 8 ... and so on when the same program is being executed with redirected stdout it will be a 10 second delay, and after that all numbers are displayed. If i put fflush(stdout) in the loop in asyncapp the application will work as it is supposed to do even when spawned with redirected handles. The problem is that i am trying to redirect a third-party application for which i dont have the sources.

Will overlapped I/O solve this problem, or should i seek answers elsewhere?

Thanks in advice,
Oskar Sjöberg
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 9601331

I have not compiled your code, but as a first impression, I dont think Overlapped IO will NOT solve your problem. I have not tried io redirection my myself yet. However I had a similar problem on Unix I remember, and fflush() was the method I used there either:) Yes there is some buffering assiciated with stdio's. I dont know if there is a way to get aroung this..  I'll let u know if I find something..

~ J
0
 

Accepted Solution

by:
CetusMOD earned 0 total points
ID: 10869862
PAQed, with points refunded (50)

CetusMOD
Community Support Moderator
0

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question