in reply to Re^8: Threads: How to share a FileHandle to Write
in thread Threads: How to share a FileHandle to Write
I'm replying here cos it's too much to do via /msg
gulden says We can clone filehandles, but can u ensure tha they share buffers, locks and son on?
On (native) Win32 & Win64 I'll give you a qualified yes. On the evidence of your posts, maybe not on other (POSIX) platforms.
To the best ability to track this through, the difference lies somewhere below this function in sv.c:
PerlIO * PerlIO_fdupopen(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags) { #if defined(PERL_MICRO) || defined(__SYMBIAN32__) return NULL; #else #ifdef PERL_IMPLICIT_SYS return PerlSIO_fdupopen(f); #else #ifdef WIN32 return win32_fdupopen(f); #else if (f) { const int fd = PerlLIO_dup(PerlIO_fileno(f)); if (fd >= 0) { char mode[8]; #ifdef DJGPP const int omode = djgpp_get_stream_mode(f); #else const int omode = fcntl(fd, F_GETFL); #endif PerlIO_intmode2str(omode,mode,NULL); /* the r+ is a hack */ return PerlIO_fdopen(fd, mode); } return NULL; } else { SETERRNO(EBADF, SS_IVCHAN); } #endif return NULL; #endif #endif }
With the Win* versions complying with this description from the POSIX standard:
The object referenced by the descriptor does not distinguish betw +een fildes and fildes2 in any way. Thus if fildes2 and fildes are du +plicate references to an open file, read(2), write(2) and lseek(2) calls +all move a single pointer into the file, and append mode, non-blocking I/O + and asynchronous I/O options are shared between the references. If a + sepa- rate pointer into the file is desired, a different object referen +ce to the file must be obtained by issuing an additional open(2) call. + The close-on-exec flag on the new file descriptor is unset.
other (ironically POSIX) platforms not!
I'm guessing (on the basis of little more than gut feel and my abortive attempts to trace this through perlio.c, that the problem lies with the perlio implementation of the dup2 semantics rather than the underlying OSs (which would have noticed this much earlier).
If you compile your own Perl on one of those platforms, then you could try using stdio instead of perlio and confirm or not my suspicions. Alternatively, put together a simple testcase that demonstrates the problem (or use mine from above that works for me and fails for you), and raise a PerlBug.
As for locking: you don;t need to be able to share the filehandle in order to use locking. You declare a simple shared scalar and perform your locking on that.
Sorry that I cannot explain this better, nor help you with non-Win* platforms.
|
|---|