Jeffrey Altman wrote:
Rainer:

Thank you for the patch.  The second block of your patch is indeed a
deadlock that must be fixed.  The first block of your patch affects
code that has been changed on the 1.4.x branch.  Please examine the
attached patch.


No, I'm afraid that's not sufficient: after dropping and re-acquiring the locks it may well be that the rxcon_client has changed again.

Therefore you need the

while (... && ... && ...) / continue instead of the if (...) construct.

I came up with the patch from the 1.4.1 base and wasn't aware
of the rxr_CidOf() changes.

Attached is the patch against 1.57.2.36, but re-applied through cut & paste and neither tested nor even compiled.


--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rainer Toebbicke
European Laboratory for Particle Physics(CERN) - Geneva, Switzerland
Phone: +41 22 767 8985       Fax: +41 22 767 7155
--- /tmp/host.c.o141    2006-06-20 16:55:02.000000000 +0200
+++ /tmp/host.c 2006-06-20 17:00:30.000000000 +0200
@@ -1758,9 +1758,12 @@
      * required).  So, before setting the RPC's rock, we should disconnect
      * the RPC from the other client structure's rock.
      */
-    oldClient = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
-    if (oldClient && oldClient->sid == rxr_CidOf(tcon)
-       && oldClient->VenusEpoch == rxr_GetEpoch(tcon)) {
+    while (
+       (oldClient = (struct client *)rx_GetSpecific(tcon, rxcon_client_key))
+       && oldClient != client
+       && oldClient->sid == rxr_CidOf(tcon)
+       && oldClient->VenusEpoch == rxr_GetEpoch(tcon)
+    ) {
        char hoststr[16];
        if (!oldClient->deleted) {
            /* if we didn't create it, it's not ours to put back */
@@ -1782,9 +1785,12 @@
                FreeCE(client);
                created = 0;
            } 
-           ObtainWriteLock(&oldClient->lock);
            oldClient->refCount++;
+           H_UNLOCK;
+           ObtainWriteLock(&oldClient->lock);
+           H_LOCK;
            client = oldClient;
+           continue;                           /* all locks dropped, re-check 
*/
        } else {
            ViceLog(0, ("FindClient: deleted client %x(%x) already had conn %x 
(host %s:%d), stolen by client %x(%x)\n", 
                        oldClient, oldClient->sid, tcon, 

Reply via email to