On 09/14/2015 02:18 AM, Alexandre Julliard wrote:
Daniel Santos daniel.santos@pobox.com writes:
As you can see this can get more complicated. If the server discovers that an server object isn't signaled it will have to notify the client to rollback the locks and wait for server objects to be ready.
So which of these solution is most appealing to you?
None of them, really.
Using shared memory means you'll need one page per object, because you can't allow a process to corrupt the state of unrelated objects. This doesn't scale.
I have considered this as well, and my idea was to have a shared page (or set of pages if needed) for each unique combination of processes that are sharing objects. Then these pages will only contain objects that are shared by all of those processes. The synchronization object in private memory is then "moved" (or just redirects) to the new object in shared memory and any threads waiting on the old one are signaled and a flag in the old object informs them of the move, so they can start over on the new object. Actually, the original object doesn't go away, it just becomes a proxy. This can happen again if the sharing scheme changes to involve another process, except that the now-intermediary object can actually be "deleted" once there are no more references to it (not really a call to free() of course).
SysV synchronization objects are broken in various ways and should be avoided.
That's good to know!
I think the most promising approach would be to add a process-local cache for objects that don't need inter-process synchronization. As soon as the object needs complex work that involves the server or another process (DuplicateHandle, WaitForMultipleObjects, named objects, etc.) it graduates to a full server object, and from then on goes through the normal path. This should cover the most performance-critical cases.
That is actually a wonderful idea! The struct ntdll_object & associated rbtree and list added to om.c in the patch set is exactly for this process-level cache. Rather the object is inter-process or not can just be data in that cache object. This would seem to add the most for the least complexity and exposure to security and corruption issues. This approach should fix most performance issues and still be very simple! :) Thanks!
I was going to have to ask about the message queues needing to have their signaled() functions called during a select call (which was a complication I hadn't mentioned) but this avoids that issues now.
Daniel