http://bugs.winehq.org/show_bug.cgi?id=17195
--- Comment #38 from Luke Kenneth Casson Leighton lkcl@lkcl.net 2011-12-14 17:40:51 CST --- adam, hi,
it's good to see someone finally working on this. here's some notes on what i discovered.
* the use of one socket per message, which was the only way to get the correct kind of blocking semantics, very very quickly exhausts the max number of open filedescriptors of any system.
* logically, therefore, the only way in which the correct blocking semantics (on a filedescriptor) can be achieved is also not a viable way.
* therefore, logically, there is no point in pursuing - by enhancement or otherwise - the approach taken in this demonstration patch which otherwise successfully and correctly implements proper namedpipe datagrams.
* therefore, logically, this has to be done correctly.
the correct way to do this is for the blocking semantics to be implemented as a *userspace* service (running under wine). it's to do with threads, and the fact that the wine "server" is single-threaded, blocking, and is designed around the "asynchronous" concept.
the alternative is a complete nightmare, requiring *everything* to do with NamedPipes (networked or otherwise) to be *entirely* implemented as "kernel-side" - i.e. asynchronous and single-threaded.
that includes services as well.
now, naively, that sounds all lovely and wonderful, until you go looking at the asynchronous libsmb code in samba, which is of course GPL'd so it *cannot* be used and would require complete reimplementation, and you find that it's tens of thousands of lines of code.
there is a much simpler alternative: use *existing* synchronous libraries, code and services - in fact you could simply modify samba (or better have a look at samba-tng which already has been ported to Win32) and *don't* go reinventing the wheel.
howeverrrr... before you get there, you have to provide a means by which client userspace applications can call into kernelspace, and for kernelspace to call *back* to userspace [the alternative being to reimplement all of said libraries and services as asynchronous code, in kernelspace].
if you've been following closely up until now, you may have an inkling of what the problem is.
the problem is that when a wine userspace application calls a kernelspace function call (e.g. WriteFile on a pipe), there's only one "thread", kernel-side, and it permanently and completely blocks *all* and *any* userspace applications until that quotes kernelspace quotes function has been serviced.
in other words, if you passed the data on to another userspace application, it would cause deadlock.
the solution is: to make wineserver multi-threaded.
this is, btw, unavoidable, absolutely essential, and it is inevitable that wineserver _will_ have to be made multi-threaded. denial of this fact will only continue to result in obscure and inexplicable failures over the years, inexplicable slow operation of wine under certain conditions, and so on.
now, the last time i described this, i was told, incredibly curtly and very rudely, that "this was pure speculation" by dmitri (comment #34)
if i get that kind of shit treatment again, which is entirely unacceptable in a free software environment, i will simply request that my account on bugs.winehq.org be deleted, and you (plural) will never receive the benefit of my advice or experience in this highly complex and specialist area, ever again.
anyway.
you'll notice in NT documentation that several function calls are marked as kernel-level blocking or otherwise. it really is absolutely critical for wineserver to mirror this behaviour. it may be worthwhile seeing what the ReactOS team have done.
also, given that wine is itself so fundamentally, fundamentally dependent on NamedPipes, now, it really really is essential to implement a lrpc namespace in ncalrpc, so that the fundamental services such as \pipe\svcctl can operate unimpeded whilst development and testing is taking place! ncalrpc using the NamedPipe functions is *incorrect*. the implementation of ncalrpc doesn't actually matter - it could be a complete duplicate of the entire NamedPipe code right now just with function call renames as long as it's fixed later (to also have correct message-passing semantics).
so... lots to do, but this is all pretty low-level and critical stuff, it's a credit to the implementation of wine that it's got this far _without_ tackling these thorny issues :)
l.