diff --git a/src/XrdClient/Makefile.am b/src/XrdClient/Makefile.am
index dc69c12..0dd87ec 100644
--- a/src/XrdClient/Makefile.am
+++ b/src/XrdClient/Makefile.am
@@ -83,7 +83,7 @@ libXrdClient_la_LIBADD = $(LIBSUNMATH) \
               ../XrdNet/libXrdNet.la \
               ../XrdOuc/libXrdOuc.la \
               ../XrdSys/libXrdSys.la \
-              ../XrdNet/libXrdNetUtil.la
+              ../XrdNet/libXrdNetUtil.la -lpthread
 
 clientlibs =  libXrdClient.la \
               -ldl $(LIBZ)
diff --git a/src/XrdClient/XrdClient.cc b/src/XrdClient/XrdClient.cc
index 7bbef76..b2ecfee 100644
--- a/src/XrdClient/XrdClient.cc
+++ b/src/XrdClient/XrdClient.cc
@@ -1228,9 +1228,10 @@ bool XrdClient::Close() {
     fConnModule->SendGenCommand(&closeFileRequest,
 				0,
 				0, 0 , FALSE, (char *)"Close");
-  
+
     // No file is opened for now
     fOpenPars.opened = FALSE;
+    fConnModule->Disconnect( false );
 
     return TRUE;
 }
diff --git a/src/XrdClient/XrdClientConn.cc b/src/XrdClient/XrdClientConn.cc
index acef9ca..003e340 100644
--- a/src/XrdClient/XrdClientConn.cc
+++ b/src/XrdClient/XrdClientConn.cc
@@ -274,8 +274,8 @@ short XrdClientConn::Connect(XrdClientUrlInfo Host2Conn,
 void XrdClientConn::Disconnect(bool ForcePhysicalDisc)
 {
     // Disconnect... is it so difficult? Yes!
-
-    ConnectionManager->SidManager()->GetAllOutstandingWriteRequests(fPrimaryStreamid, fWriteReqsToRetry);
+    if( ConnectionManager->SidManager() )
+      ConnectionManager->SidManager()->GetAllOutstandingWriteRequests(fPrimaryStreamid, fWriteReqsToRetry);
 
     if (fMainReadCache && (DebugLevel() >= XrdClientDebug::kDUMPDEBUG) ) fMainReadCache->PrintCache();
 
diff --git a/src/XrdClient/XrdClientConn.hh b/src/XrdClient/XrdClientConn.hh
index 545b40c..472bae4 100644
--- a/src/XrdClient/XrdClientConn.hh
+++ b/src/XrdClient/XrdClientConn.hh
@@ -27,6 +27,7 @@
 #include "XrdOuc/XrdOucHash.hh"
 
 #define ConnectionManager XrdClientConn::GetConnectionMgr()
+#define SessionIDRepo     XrdClientConn::GetSessionIDRepo()
 
 class XrdClientAbs;
 class XrdSecProtocol;
@@ -289,6 +290,9 @@ public:
     static XrdClientConnectionMgr *GetConnectionMgr()
     { return fgConnectionMgr;} //Instance of the conn manager
 
+    static XrdOucHash<SessionIDInfo> &GetSessionIDRepo()
+    { return fSessionIDRepo; }
+
     void GetSessionID(SessionIDInfo &sess) {
       XrdOucString sessname;
       char buf[20];
diff --git a/src/XrdClient/XrdClientConnMgr.cc b/src/XrdClient/XrdClientConnMgr.cc
index eec98f9..9d8cc59 100644
--- a/src/XrdClient/XrdClientConnMgr.cc
+++ b/src/XrdClient/XrdClientConnMgr.cc
@@ -137,11 +137,12 @@ int DestroyPhyConn(const char *key,
 			  XrdClientPhyConnection *p, void *voidcmgr)
 {
   // Function applied to the hash table to destroy all the phyconns
-
   XrdClientConnectionMgr *cmgr = (XrdClientConnectionMgr *)voidcmgr;
   assert(cmgr != 0);
 
   if (p) {
+    p->Touch();
+    p->Disconnect();
     p->UnsolicitedMsgHandler = 0;
     delete(p);
   }
@@ -158,55 +159,81 @@ XrdClientConnectionMgr::XrdClientConnectionMgr() : fSidManager(0),
    // XrdClientConnectionMgr constructor.
    // Creates a Connection Manager object.
    // Starts the garbage collector thread.
+   BootUp();
 
-   fLastLogIdUsed = 0;
+}
 
-   fGarbageColl = new XrdClientThread(GarbageCollectorThread);
-   
-   if (!fGarbageColl)
-      Error("ConnectionMgr",
-            "Can't create garbage collector thread: out of system resources");
-   
-   fGarbageColl->Run(this);
+//_____________________________________________________________________________
+XrdClientConnectionMgr::~XrdClientConnectionMgr()
+{
+   // Deletes mutex locks, stops garbage collector thread.
+  ShutDown();
+}
+
+//------------------------------------------------------------------------------
+// Initializer
+//------------------------------------------------------------------------------
+bool XrdClientConnectionMgr::BootUp()
+{
+  fLastLogIdUsed = 0;
 
+  fGarbageColl = new XrdClientThread(GarbageCollectorThread);
 
-   fSidManager = new XrdClientSid();
-   if (!fSidManager) {
+  if (!fGarbageColl)
      Error("ConnectionMgr",
-	   "Can't create sid manager: out of system resources");
-     abort();
-   }
+           "Can't create garbage collector thread: out of system resources");
+
+  fGarbageColl->Run(this);
+
+  fSidManager = new XrdClientSid();
+  if (!fSidManager) {
+    Error("ConnectionMgr",
+   "Can't create sid manager: out of system resources");
+    abort();
+  }
 
+  return true;
 }
 
-//_____________________________________________________________________________
-XrdClientConnectionMgr::~XrdClientConnectionMgr()
+bool XrdClientConnectionMgr::ShutDown()
 {
-   // Deletes mutex locks, stops garbage collector thread.
+  fPhyHash.Apply(DumpPhyConn, this);
 
-   int i=0;
+  {
+    XrdSysMutexHelper mtx(fMutex);
 
-   {
-      XrdSysMutexHelper mtx(fMutex);
+    for( int i = 0; i < fLogVec.GetSize(); i++)
+      if (fLogVec[i]) Disconnect(i, TRUE);
+  }
 
-      for (i = 0; i < fLogVec.GetSize(); i++)
-	 if (fLogVec[i]) Disconnect(i, FALSE);
+  if (fGarbageColl)
+  {
+    void *ret;
+    fGarbageColl->Cancel();
+    fGarbageColl->Join(&ret);
+    delete fGarbageColl;
+  }
 
-   }
+  GarbageCollect();
 
-   if (fGarbageColl) {
-     void *ret;
-      fGarbageColl->Cancel();
-      fGarbageColl->Join(&ret);
-      delete fGarbageColl;
-   }
+  fPhyHash.Apply(DestroyPhyConn, this);
+
+  for(int i = fPhyTrash.GetSize()-1; i >= 0; i--)
+    DestroyPhyConn( "Trashed connection", fPhyTrash[i], this);
+
+  fPhyTrash.Clear();
+  fPhyHash.Purge();
+  fLogVec.Clear();
+
+  delete fSidManager;
 
-   GarbageCollect();
+  fSidManager  = 0;
+  fGarbageColl = 0;
 
-   fPhyHash.Apply(DestroyPhyConn, this);
-   delete fSidManager;
+  return true;
 }
 
+
 //_____________________________________________________________________________
 void XrdClientConnectionMgr::GarbageCollect()
 {
@@ -521,7 +548,7 @@ void XrdClientConnectionMgr::Disconnect(int LogConnectionID,
 	 return;
       }
 
-
+      fLogVec[LogConnectionID]->GetPhyConnection()->WipeStreamid(fLogVec[LogConnectionID]->Streamid());
       if (ForcePhysicalDisc) {
 	 // We disconnect the phyconn
 	 // But it will be removed by the garbagecollector as soon as possible
@@ -532,8 +559,7 @@ void XrdClientConnectionMgr::Disconnect(int LogConnectionID,
 	 fLogVec[LogConnectionID]->GetPhyConnection()->Disconnect();
 	 GarbageCollect();
       }
-      else
-         fLogVec[LogConnectionID]->GetPhyConnection()->WipeStreamid(fLogVec[LogConnectionID]->Streamid());
+
     
       fLogVec[LogConnectionID]->GetPhyConnection()->Touch();
       delete fLogVec[LogConnectionID];
diff --git a/src/XrdClient/XrdClientConnMgr.hh b/src/XrdClient/XrdClientConnMgr.hh
index 7bb3ba7..bdb2bab 100644
--- a/src/XrdClient/XrdClientConnMgr.hh
+++ b/src/XrdClient/XrdClientConnMgr.hh
@@ -80,6 +80,10 @@ public:
 
    virtual ~XrdClientConnectionMgr();
 
+  bool BootUp();
+  bool ShutDown();
+
+
    int           Connect(XrdClientUrlInfo RemoteAddress);
    void          Disconnect(int LogConnectionID, bool ForcePhysicalDisc);
 
diff --git a/src/XrdClient/XrdClientEnv.cc b/src/XrdClient/XrdClientEnv.cc
index f0d70d1..1a888f4 100644
--- a/src/XrdClient/XrdClientEnv.cc
+++ b/src/XrdClient/XrdClientEnv.cc
@@ -14,9 +14,12 @@
 #include "XrdSys/XrdSysHeaders.hh"
 #include "XrdClient/XrdClientConst.hh"
 #include "XrdClient/XrdClientEnv.hh"
+#include "XrdClient/XrdClientConn.hh"
+#include "XrdClient/XrdClientConnMgr.hh"
 #include <string>
 #include <algorithm>
 #include <ctype.h>
+#include <iostream>
 
 XrdClientEnv *XrdClientEnv::fgInstance = 0;
 
@@ -152,3 +155,51 @@ XrdClientEnv::~XrdClientEnv() {
 
    fgInstance = 0;
 }
+
+//------------------------------------------------------------------------------
+// To be called prior to forking
+//------------------------------------------------------------------------------
+static void prepare()
+{
+  ConnectionManager->ShutDown();
+  SessionIDRepo.Purge();
+}
+
+//------------------------------------------------------------------------------
+// To be called in the parent just after forking
+//------------------------------------------------------------------------------
+static void parent()
+{
+  ConnectionManager->BootUp();
+}
+
+//------------------------------------------------------------------------------
+// To be called in the child just after forking
+//------------------------------------------------------------------------------
+static void child()
+{
+  ConnectionManager->BootUp();
+}
+
+//------------------------------------------------------------------------------
+// Install the fork handlers on application startup
+//------------------------------------------------------------------------------
+namespace
+{
+  static struct Initializer
+  {
+    Initializer()
+    {
+      //------------------------------------------------------------------------
+      // Install the fork handlers
+      //------------------------------------------------------------------------
+#ifndef WIN32
+      if( pthread_atfork( prepare, parent, child ) != 0 )
+      {
+        std::cerr << "Unable to install the fork handlers - safe forking not ";
+        std::cerr << "possible" << std::endl;
+      }
+#endif
+    }
+  } initializer;
+}
diff --git a/src/XrdClient/XrdClientEnv.hh b/src/XrdClient/XrdClientEnv.hh
index 5d84e1b..5c6bbc5 100644
--- a/src/XrdClient/XrdClientEnv.hh
+++ b/src/XrdClient/XrdClientEnv.hh
@@ -91,8 +91,7 @@ class XrdClientEnv {
       fOucEnv->PutInt(varname, value);
    }
 
-   static XrdClientEnv    *Instance();
-
+  static XrdClientEnv *Instance();
 };
 
 #endif
diff --git a/src/XrdClient/XrdClientPhyConnection.cc b/src/XrdClient/XrdClientPhyConnection.cc
index a9c56d4..cfdbb52 100644
--- a/src/XrdClient/XrdClientPhyConnection.cc
+++ b/src/XrdClient/XrdClientPhyConnection.cc
@@ -45,21 +45,16 @@ void *SocketReaderThread(void * arg, XrdClientThread *thr)
 
    XrdClientPhyConnection *thisObj;
 
+
    Info(XrdClientDebug::kHIDEBUG,
 	"SocketReaderThread",
 	"Reader Thread starting.");
 
-   thr->SetCancelDeferred();
-   thr->SetCancelOn();
-
    thisObj = (XrdClientPhyConnection *)arg;
-
    thisObj->StartedReader();
 
    while (1) {
-     thr->SetCancelOff();
      thisObj->BuildMessage(TRUE, TRUE);
-     thr->SetCancelOn();
 
      if (thisObj->CheckAutoTerm())
 	break;
@@ -110,6 +105,15 @@ XrdClientPhyConnection::~XrdClientPhyConnection()
        "Destroying. [" << fServer.Host << ":" << fServer.Port << "]");
 
    Disconnect();
+  if (fReaderthreadrunning)
+    for (int i = 0; i < READERCOUNT; i++)
+      if(fReaderthreadhandler[i])
+      {
+        fReaderthreadhandler[i]->Join();
+        delete fReaderthreadhandler[i];
+      }
+
+
 
      if (fSocket) {
         delete fSocket;
@@ -118,13 +122,6 @@ XrdClientPhyConnection::~XrdClientPhyConnection()
 
    UnlockChannel();
 
-   if (fReaderthreadrunning) 
-      for (int i = 0; i < READERCOUNT; i++)
-	if (fReaderthreadhandler[i]) {
-	  fReaderthreadhandler[i]->Cancel();
-	  fReaderthreadhandler[i]->Join();
-	  delete fReaderthreadhandler[i];
-	}
 
    if (fSecProtocol) {
       // This insures that the right destructor is called
@@ -232,12 +229,6 @@ void XrdClientPhyConnection::StartReader() {
          exit(-1);
       }
 
-      if (fReaderthreadhandler[i]->Detach())
-      {
-	 Error("PhyConnection", "Thread detach failed");
-	 //return;
-      }
-
       }
       // sleep until at least one thread starts running, which hopefully
       // is not forever.
