FLTK logo

STR #2107

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 Home  |  Articles & FAQs  |  Bugs & Features  |  Documentation  |  Download  |  Screenshots  ]
 

Return to Bugs & Features | SVN ⇄ GIT ]

STR #2107

Application:FLTK Library
Status:2 - Closed w/o Resolution
Priority:1 - Request for Enhancement, e.g. asking for a feature
Scope:2 - Specific to an operating system
Subsystem:OS support
Summary:WIN32: Fl::add_fd does not work well with anonymous pipes
Version:1.4-feature
Created By:manolo
Assigned To:manolo
Fix Version:1.3-current
Update Notification:

Receive EMails Don't Receive EMails

Trouble Report Files:


Name/Time/Date Filename/Size  
 
#1 manolo
02:30 Dec 20, 2008
pseudoterminal.cxx
9k
 
     

Trouble Report Comments:


Name/Time/Date Text  
 
#1 manolo
22:48 Dec 19, 2008
I find that, under WIN32, Fl::add_fd works only superficially when the monitored file descriptor is an anonymous pipe. I don't know if you know that already perfectly, but the documentation is silent on this subject. (Under Mac OS X and X11, add_fd works beautifully on pipes.)
If data comes steadily from the pipe, all is well, but if the pipe remains empty for a long time, this happens:
Fl::wait() calls select
select returns that the fd is to be read (note that select is sold for sockets on WIN32, not for pipes)
Fl::wait() calls the fd's callback
which calls read(fd,...)
which blocks until some data arrives in the pipe.

The result is that the GUI, blocked in Fl::wait(), is frozen.

So I use the following code, that does not block when the pipe is empty, to monitor pipe incoming data:
DWORD avail = 0;
//is there data in pipe ?
PeekNamedPipe(_get_osf_handle(fd), NULL,0,NULL, &avail, NULL);
if(avail > 0) read(fd,...) //read data from pipe

Another call that correctly detects whether there is data to be read in the pipe is:
if( WaitForSingleObject(_get_osf_handle(fd), 0) == WAIT_OBJECT_0)
but it is unclear for me how to detect pipe closure by its writer,
so all of this does not really solve how to write under WIN32 Fl::wait()
generically for any fd as it is under Unix.
 
 
#2 greg.ercolano
00:12 Dec 20, 2008
Is the data you're transmitting ASCII and delimited by CRLFs? If so, make sure the child is flushing its output regularly enough. If you're sending binary data, be sure both ends of the pipe agree on the blocking size.

Try to include a *small* example program here showing the FLTK app and the child, and how the two are interacting.

FWIW, I decided quickly Microsoft did not do a great job implementing the unixy functions for pipes (eg. select()/read()/etc. for pipes), however, I found their WIN32 API calls like CreatePipe() + CreateProcess() (and related calls) are fairly reliable. To use them effectively, I found it involved making a child thread to handle reading the pipe, so if it blocked, FLTK was unaffected. When data was fully ready, the child would dump it in a buffer common to the two threads, and set a flag. The FLTK parent thread would use an FLTK timer to keep an eye on the flag, and when set, would lock the data and read it, then clear the flag. This way there was no chance the FLTK thread would hang up waiting for data; the child thread would deal with it, and could hang as much as it liked.
 
 
#3 greg.ercolano
00:23 Dec 20, 2008
> I find that, under WIN32, Fl::add_fd works only superficially
> when the monitored file descriptor is an anonymous pipe. I don't
> know if you know that already perfectly, but the documentation
> is silent on this subject.

    BTW, the docs on Fl::add_fd() seem to be fairly distinct
    about this:
    http://fltk.org/documentation.php/doc-1.1/Fl.html#Fl.add_fd

    Quoting the docs:
    "Under UNIX any file descriptor can be monitored (files,
     devices, pipes, sockets, etc.) **Due to limitations in
     Microsoft Windows, WIN32 applications can only monitor sockets.**"

    So I read that to mean what you're doing is specifically not
    supported.

    I think this limitation has to do with how Microsoft implemented
    select() for BSD network sockets only, and not an across the board
    solution for all the things the win32 select() function supports,
    such as pipes.. named or otherwise.

    I think you're right to follow your instincts to go with the
    WIN32 API calls under windows. My reply above about how to use
    a child thread to read the pipe into a buffer and an FLTK timer
    to lock/read the buffer is a reliable method.
 
 
#4 manolo
02:29 Dec 20, 2008
Many thanks for the fast and exhaustive replies.
I am sorry not to have seen the explicit limitation of Fl::add_fd
to sockets under WIN32 in the documentation. 
So I understand pipe monitoring is not supported by FLTK under WIN32.

Just in case, I attach my solution to my problem: run an external program in a pseudoterminal window built by FLTK to receive the program's output,
with the possibility to interrupt this program. It is essentially the same as fluid's Fl_Process.
The interface is function run_external_prog_in_pseudoterm,
and its works nicely on all 3 windowing systems.
 
 
#5 matt
09:40 Dec 20, 2008
add_fd only works with sockets on MSWindows as mentioned in the docs. The soluton could be a Fl_Pipe class fro cross-platform availibility.  
 
#6 manolo
23:33 Mar 10, 2015
The doc explicitly states that Fl::add_fd does not work
with anonymous pipes under MSWindows.
 
     

Return to Bugs & Features ]

 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.