OBones wrote:
Mark Morgan Lloyd wrote:
A couple of weeks ago, out of curiosity rather than necessity, I started looking at whether the library could be ported to Windows using MS-style named pipes. However I seem to have hit a snag since it appears that Windows can't both create a named pipe (for reading) and open the same named pipe (for writing) in the same process, something that gives unix sockets no problems at all.
Could you show us some code here?
And what return values do you get?
I'm asking because I have distinct memories of doing just that a while back without any issue.

I've certainly done it to communicate between separate processes, but the difference in the current case is that the first time the program is loaded I'm enqueueing its own parameters rather than passing them via an in-memory "shortcut"... works fine in unix and seemed like a good idea at the time :-) It's strange though just how many people on StackOverflow etc. say things like "using a named pipe to communicate inside a single process is utterly pointless", it's almost as though they're parroting some doctrine the origin of which is now lost.

Basically, what I was trying to do was this. In the main thread:

    fIpcPipe:= CreateNamedPipe(PChar(fIpcName), PIPE_ACCESS_INBOUND,
                        PIPE_TYPE_MESSAGE + PIPE_READMODE_MESSAGE,
                                1, 0, 0, 1000, NIL (* @sa *) );

That works. Fire up a background reader thread, and make sure that the main thread doesn't proceed...

    fThread:= TSphinxThread.Create(false);
while fThread.fSyncParam = DEADBEEF DO (* Until thread has called ConnectNamedPipe() *)
      Sleep(10);
    fThread.Suspend

..until after the Execute in the reader thread has done:

fSyncParam := ''; (* Let main process see that we've started *)
{$ifndef UNIX }
  IF NOT ConnectNamedPipe(Phix.Pipe, NIL) THEN
    EXIT;
{$endif UNIX  }
  WHILE NOT Terminated DO BEGIN

I'm keenly aware of the deprecated status of calling Suspend from outside the thread, but what I'm showing there is just one attempt from many.

Finally, once the main thread is confident that the background reader has got to the point of being connected to the named pipe:

sendPipe:= CreateFile(PChar(fIpcName), GENERIC_WRITE, FILE_SHARE_WRITE + FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  IF sendPipe = INVALID_HANDLE_VALUE THEN BEGIN
fSlaveInitErrorNum:= GetLastError; (* 230: bad pipe. 231: pipe busy. *)

That invariably fails with an error 231, at which point after quite a lot of tinkering and comparison against my older code I gave up.

--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to