// @(#)root/proofx:$Id: TXUnixSocket.cxx 24719 2008-07-09 07:07:25Z ganis $
// Author: Gerardo Ganis  12/12/2005

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TXUnixSocket                                                         //
//                                                                      //
// Implementation of TXSocket using PF_UNIX sockets.                    //
// Used for the internal connection between coordinator and proofserv.  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
#ifdef OLDXRDOUC
#  include "XrdSysToOuc.h"
#  include "XrdOuc/XrdOucPthread.hh"
#else
#  include "XrdSys/XrdSysPthread.hh"
#endif

#include "TXUnixSocket.h"
#include "XrdProofPhyConn.h"

ClassImp(TXUnixSocket)

//_____________________________________________________________________________
TXUnixSocket::TXUnixSocket(const char *url,
                           Int_t psid, Char_t capver, TXHandler *handler)
             : TXSocket(0,'i',psid,capver,0,-1,handler)
{
   // Constructor

   // Initialization
   if (url) {

      // Create connection
      fConn = new XrdProofPhyConn(url, psid, capver, this);
      if (!(fConn->IsValid())) {
         Error("TXUnixSocket", "severe error occurred while opening a connection"
                               " to server [%s]", fUrl.Data());
         return;
      }

      // Fill some info
      fUser = fConn->fUser.c_str();
      fHost = fConn->fHost.c_str();
      fPort = fConn->fPort;
      fXrdProofdVersion = fConn->fRemoteProtocol;
      fRemoteProtocol = fConn->fRemoteProtocol;

      // Save also updated url
      TSocket::fUrl = fConn->fUrl.GetUrl().c_str();

      // This is needed for the reader thread to signal an interrupt
      fPid = gSystem->GetPid();
   }
}

//______________________________________________________________________________
Int_t TXUnixSocket::Reconnect()
{
   // Try reconnection after failure

   if (gDebug > 0) {
      Info("Reconnect", "%p: %p: %d: trying to reconnect on %s", this,
                        fConn, (fConn ? fConn->IsValid() : 0), fUrl.Data());
   }

   if (fXrdProofdVersion < 1005) {
      Info("Reconnect","%p: server does not support reconnections (protocol: %d < 1005)",
                       this, fXrdProofdVersion);
      return -1;
   }


   if (fConn && !fConn->IsValid()) {

      // Block any other attempt to use this connection
      XrdSysMutexHelper l(fConn->fMutex);

      fConn->Close();
      int maxtry, timewait;
      XrdProofConn::GetRetryParam(maxtry, timewait);
      XrdProofConn::SetRetryParam(300, 1);
      fConn->Connect();
      XrdProofConn::SetRetryParam();
   }

   if (gDebug > 0) {
      Info("Reconnect", "%p: %p: attempt %s", this, fConn,
                        ((fConn && fConn->IsValid()) ? "succeeded!" : "failed"));
   }

   // Done
   return ((fConn && fConn->IsValid()) ? 0 : -1);
}
