2009/2/16 Joe Orton <jor...@redhat.com>: > On Sat, Feb 14, 2009 at 10:25:08AM +1100, Graham Dumpleton wrote: > ... >> What the end result of the code is, is that if you have a file bucket >> getting this far where length of file is less than 8000 and an EOS >> follows it, then the actual file bucket is held over rather than data >> being read and buffered. This is as commented is to avoid doing an >> mmap+memcpy. What it means though is that the file descriptor within >> the file bucket must be maintained and cannot be closed as soon as >> ap_pass_brigade() has been called. > > The call to: > > ap_save_brigade(f, &ctx->b, &b, ctx->deferred_write_pool); > > in that code path should result in the FILE bucket and the contained fd > being dup()ed. (Though if that is failing, you wouldn't know because of > the lack of error checking) > > You say: > >> For me this is an issue as the file descriptor has been supplied from >> a special object returned by a higher level application and it would >> be hard to maintain the file as open beyond the life of the request, >> up till end of keep alive or a subsequent request over same >> connection. Doing a dup on the file decriptor is also not necessarily >> an option. > > can you explain why a dup shouldn't work?
I did used to perform a dup, but was told that this would cause problems with file locking. Specifically was told: """I am not sure, but it looks like mod_wsgi duplicates the original file descriptor, sends the file's data, closes the duplicated file descriptor, and then calls the iterable's close method. That may be problematic for applications that are using fcntl-based locking; the closing of the duplicate file descriptor will release the lock before the iterable's close method gets a chance to execute, so the close method can no longer depend on the file remaining locked. Ideally, the duplicate file descriptor shouldn't be closed until *after* the iterable's close() method has been called.""" I never researched it properly as didn't have time at that point, so simply believed what was being told. A quick check of flock manual page says: """Locks created by flock() are associated with an open file table entry. This means that duplicate file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock may be modified or released using any of these descriptors. Furthermore, the lock is released either by an explicit LOCK_UN operation on any of these duplicate descriptors, or when all such descriptors have been closed.""" So for flock() there is no problem. As to fcntl locking which person mentioned, I haven't been able to find yet any description of the behaviour of locks in context of dup'd file descriptors. If you know of source of information which explains what happens for fcntl locking and dup'd file descriptors that would help clear things up. In the mean time I'll keep looking for any information about it. Graham