Closed Bug 300455 Opened 19 years ago Closed 15 years ago

Further improvements of DCONNECT, an IPC extension to support distributed XPCOM

Categories

(Core :: IPC, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: dmik, Unassigned)

Details

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4

Here are my patches to the DCONNECT extension and the description of the changes.

The changes are aimed to improve the distributed XPCOM usability and add
features such as multithreading support, nsISupports identity across process
boundaries, etc.

Reproducible: Always

Steps to Reproduce:
These are my current patches to the release 1.8a4 of the Mozilla codebase. I'm
stuck to the MOZILLA_1_8a4_RELEASE tag in my development, however, the patches
can be successfully applied to the current head (just tried it: everything
compiles, but I didn't perform any functional tests). The description of
changes will follow.
cool! We'll look at this for the early-1.9 timeframe.
Status: UNCONFIRMED → NEW
Ever confirmed: true
The brief list of changes made by the above patch (in the chronological order):

- ipdDConnectService: fixed a bug when deserializing wchar (PRUnichar) strings
  that could lead to wrong strings both on the client and on the server side, or
  to segmentation faults.

- Nested IPC calls are now processed correctly. A nested IPC call is an IPC call
  made by the party while it is serving another IPC call (for example, a client
  calls a method of some server-side object, that in turn calls some
  client-side object's method).

- ipdDConnectService: NULL string (T_CHAR_STR) and wstring (T_WHCAR_STR) values
  are passed correctly across processes both on input and on output (previously,
  an attempt to do so resulted in !NS_OK nsresult).

- ipdDConnectService: passing NULL pointers as output parameters to IPC method
  calls will return NS_ERROR_NULL_POINTER at the early stage, before sending a
  message to the object's owner (similarly to MS COM), to provide a reasonable
  feedback to the caller.

- ipcDConnectService: fixed some issues related to reference counting when
  passing interface pointers across processes (out/retval pointers serialized
  for a client were not released causing a leak, while input pointers were
  accidentally released in some cases).

- ipcDConnectService: fixed a seg. fault when destroying the service upon
  application termination (interface wrappers were deleted twice).

- IPC_Shutdown(): fixed a deadlock while trying to send a RELEASE message to the
  original object (as a result of destroying its stub) in case when it is done
  after the original object's owning process has terminated (for example,
  unexpectedly died).

- Implemented interface pointer identity across process boundaries. This means
  that if values of any two interface pointers (representing the same interface
  type) are identical in the process that owns the object, they will also be
  identical in any process that uses this object through DCONNECT. As a
  consequence, the nsISupports identity is now guaranteed across processes
  (one of the important requirements of the COM specification). This is done
  by reusing wrappers and stubs created on behalf of a particular client
  instead of creating new ones every time an interface pointer is involved in
  IPC calls (i.e. no matter how many times the same pointer is passed between
  two processes, only one wrapper/stub object for this pointer exists on each
  side). It reduces the number of wrappers/stubs being created significantly in
  some situations.

- ipcDConnectService: fixed response handling (if two or more threads
  were simultaneously attempting to call the same peer's methods, one of them
  would eat the other's responce).

- ipcDConnectService is now completely thread safe. Together with the above fix,
  it means that any thread can use the DConnect service (in particular, stubs
  representing objects on the remote side) without (hopefully) any harm.

- IPC_WaitMessage: added detection of the peer's death while waiting for the
  remote call to complete (previously, the calling side would hang in this
  situation).

- IPC_WaitMessage: IPC_SENDER_ANY wasn't actually obeyed.

- ipcDConnectService is now made multithreaded (hurray!), so incoming client
  requests are served on different threads (from a dynamically expandable
  thread pool). As a result, it means that two or more client requests
  do not block each other, but get served simultaneously instead.
  Multithreadness is enabled when DCONNECT_MULTITHREADED is defined
  (by default); DCONNECT_SINGLETHREADED returns it to the old singlethreaded
  behavior.

- ipcDConnectService: fixed the procedure of waiting for the remote method
  execution (as well as instance creation and query interface) completion reply,
  so it does not prevent other clients (processes) from being served until
  wait is finished.

- IPC_Shutdown now informs all client observers before it disconnects
  from the IPC daemon (using IPC_SENDER_ANY as the client ID), to let
  interested parties to do proper uninitialization (this includes the
  ability to use IPC_SendMessage at that point).

- ipcDConnectService sets itself up as a client observer to be informed
  when IPC_Shutdown is called (as a result of the module unload operation)
  to let all worker threads finish their work and release all stub
  instances.

- ipcDConnectService: implemented passing nsIExceptions across processes to
  make it possible to provide a calling party with extended error info
  (similarly to IErrorInfo in MS COM). If an interface method executed on behalf
  of a remote client returns an unsuccessful result code, the nsIException
  object of the execution thread is serialized (even if it is null) and
  transferred to the client together with the result code. This means, that if
  a server-side object's method called by the IPC client sets some exception
  (or resets it to null) using nsIExceptionManager::SetCurrentException() in
  case of any error, the client can use nsIExceptionManager::GetCurrentException()
  on his side to obtain exactly the same exception that was set by the server.

- nsIException is also passed to a client when an attempt to instantiate a new
  server-side component instance fails (i.e. a call to CreateInstance*() or to
  GetService*() returns an error). This way components can inform remote clients
  why they cannot be created.

Sorry for a long list, I hope I didn't forget something. If someone needs more
detail about a concrete change or the way it is implemented, I'm ready to discuss.

The patched IPC/DCONNECT extension has been used for quite some months in our
beta environment, so it seems to be rather stable under our circumstances (one
local server, a bunch of clients acting like servers too).
Here is a number of further enhancements that are in my todo list:

- Currently, all communication between to clients (A and B) is made through the
server (S) if A got an interface pointer to B's object through S. So, when A
calls B's object using this pointer, the call chain looks like: A (invoke) -> S
(invoke) -> B (reply) -> S (reply) -> A. S needs to be definitely removed from
the chain, A and B should communicate directly.

- Add a "garbage collector" that shuts down unused worker threads from time to
time. It is theoretically possible that the number of threads can grow up
significantly during lifetime.

- Handle remote client death properly to release all wrappers and stubs created
for that client.
Assignee: darin → nobody
dconnect is gone.
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → WONTFIX
QA Contact: ipc
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: