Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Error in accessing pipe "All pipe instances are busy"

Pierre_Archambeau
3,173 Views

Hi all,

I would like to communicate between two fortran processes or a commandline and a fortran process.

I try to use a named pipe.

The named pipe is created by the fortran through :   

    subroutine PipeOPEN( FILENAME )
        USE IFWIN
        IMPLICIT INTEGER (A-Z)
        CHARACTER*(*) FILENAME

        sts = CreateNamedPipe( FILENAME,             &
                          OR(PIPE_ACCESS_DUPLEX,FILE_FLAG_FIRST_PIPE_INSTANCE),       &
                          OR(OR(PIPE_TYPE_MESSAGE,PIPE_READMODE_MESSAGE),PIPE_NOWAIT),           &
                          PIPE_UNLIMITED_INSTANCES,        &
                          256,          &
                          256,           &
                          NMPWAIT_USE_DEFAULT_WAIT,       &
                          NULL)
        
    end subroutine

I got a handle.

When I want to write to the pipe, I use

            open(51,name='\\.\pipe\pierre',status='UNKNOWN',form='FORMATTED',ACTION='write')
            msg='test'
            write(51,'(a)') msg
            close(51)

But when I want to read,

open(52,name='\\.\pipe\pierre',status='UNKNOWN',form='FORMATTED',ACTION='READ')

I've got the error : "All pipe instances are busy"

The error message is the same if I want to redirect the output of a command line window.

Can you help me to resolve this issue ?

Thank in advance

 

0 Kudos
5 Replies
Paul_Curtis
Valued Contributor I
3,173 Views

1.  the filename argument to CreateNamedPipe() needs to be null-terminated

2.  IMPLICIT INTEGER(A-Z) may be legal, but is not good practice; much better to use IMPLICIT NONE and then have explicit type declarations for all variables; this also makes attributes such as the KIND for integers explicit & obvious

3.  To set multiple bitflags, the Fortran function is Inclusive-OR, IOR(flag1, flag2)

4.  Try not to use numerical values (ie, '256') directly as arguments; much better to define an integer parameter with an explicit KIND attribute

0 Kudos
Pierre_Archambeau
3,173 Views

Hi Paul,

Thank you for your remarks.

I agree with you and I adapted my code.

    subroutine PipeOPEN(FILENAME)
        USE IFWIN
        CHARACTER*(*) FILENAME
        integer(4) buff_out,buff_in, unit, sts

        buff_out = 256
        buff_in  = 256
        sts = CreateNamedPipe( trim(FILENAME)//char(0),             &
                          IOR(PIPE_ACCESS_DUPLEX,FILE_FLAG_OVERLAPPED),       &
                          IOR(IOR(PIPE_TYPE_MESSAGE,PIPE_READMODE_MESSAGE),PIPE_WAIT),           &
                          PIPE_UNLIMITED_INSTANCES,        &
                          BUFF_OUT,          &
                          BUFF_IN,           &
                          NMPWAIT_USE_DEFAULT_WAIT,       &
                          NULL)
 end subroutine

However, the conclusion is the same: "All pipe instances are busy".

Maybe do you have an example of pipes in fortran?

Thanks

Pierre

0 Kudos
Paul_Curtis
Valued Contributor I
3,173 Views

Pierre,

I have not used pipes, but I took a look at the MSDN chat on that function.  The return from sts = CreateNamedPipe() is a handle to the pipe (and should be declared INTEGER(HANDLE) :: sts), anticipating that further i/o to that pipe will be done in the customary Windows manner by, say, ReadFile() and WriteFile() which are handle-based.  This is not the same as Fortran read/write statements to a file opened with a Fortran unit number, and I cannot predict that creating a named pipe, and then subsequently attempting to re-open it as a Fortran unit for standard read/write i/o, will work.

What definitely will work, however, is to stick with Windows functions for file i/o, which are far more versatile than the older Fortran equivalents (albeit completely Windows-specific and not portable).

Let me also suggest a simple experiment. Try closing the pipe after creating it (rval = CloseHandle(sts)) and then try Fortran i/o to the pipe's filename.  Your problem may be simply that the Fortran code is failing to open a pipefile because it is already open in Windows.

 

0 Kudos
Pierre_Archambeau
3,173 Views

I solved the problem using Windows functions for file i/o as you mentioned.

On the client side, if I'm using the USEROPEN parameter of the OPEN statement to connect to the pipe with CreateFile, it's possible to use the WRITE Fortran statement with its UNIT. 

On the server side, firstly I have to use the CreateNamedPipe.  Then ConnectNamedPipe function waits a client. I don't know if it's possible to overwrite the READ statement to got the same result.

Thank you for your help.

Pierre

 

 

0 Kudos
Pierre_Archambeau
3,173 Views

To conclude, I created a functional code on https://github.com/PierreArchambeau/FortranInterProc.

I hope it can serve to anyone it concern.

Pierre

 

0 Kudos
Reply