<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#include    "../../../StroikaPreComp.h"

#include    "../../../../Foundation/Characters/Format.h"
#include    "../../../../Foundation/Characters/String_Constant.h"
#include    "../../../../Foundation/Containers/Sequence.h"
#include    "../../../../Foundation/Debug/Trace.h"
#include    "../../../../Foundation/Execution/Sleep.h"
#include    "../../../../Foundation/Execution/Thread.h"
#include    "../../../../Foundation/IO/Network/LinkMonitor.h"
#include    "../../../../Foundation/IO/Network/Socket.h"
#include    "../../../../Foundation/Streams/BasicBinaryOutputStream.h"
#include    "../../../../Foundation/Streams/TextOutputStreamBinaryAdapter.h"

#include    "../Common.h"
#include    "../Advertisement.h"
#include    "BasicServer.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::Network;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::UPnP;
using   namespace   Stroika::Frameworks::UPnP::SSDP;
using   namespace   Stroika::Frameworks::UPnP::SSDP::Server;

/*
********************************************************************************
******************************* BasicServer::Rep_ ******************************
********************************************************************************
*/
class   BasicServer::Rep_ {
public:
    Sequence<Advertisement> fAdvertisements;
    FrequencyInfo           fFrequencyInfo;
    URL                     fLocation;
    Rep_ (const Device& d, const DeviceDescription& dd, const FrequencyInfo& fi)
        : fAdvertisements ()
        , fFrequencyInfo (fi)
        , fLocation (d.fLocation)
    {
        {
            SSDP::Advertisement  dan;
            dan.fLocation = d.fLocation.GetFullURL ();
            dan.fServer = d.fServer;
            {
                dan.fTarget = kTarget_UPNPRootDevice;
                dan.fUSN = Format (L"uuid:%s::%s", d.fDeviceID.c_str (), kTarget_UPNPRootDevice.c_str ());
                fAdvertisements.Append (dan);
            }
            {
                dan.fUSN = Format (L"uuid:%s", d.fDeviceID.c_str ());
                dan.fTarget = dan.fUSN;
                fAdvertisements.Append (dan);
            }
            if (not dd.fDeviceType.empty ()) {
                dan.fUSN = Format (L"uuid:%s::%s", d.fDeviceID.c_str (), dd.fDeviceType.c_str ());
                dan.fTarget = dd.fDeviceType;
                fAdvertisements.Append (dan);
            }
        }

        StartNotifier_ ();
        StartResponder_ ();

        fLinkMonitor_ = Optional<IO::Network::LinkMonitor> (move (IO::Network::LinkMonitor ()));
        fLinkMonitor_->AddCallback ([this] (IO::Network::LinkMonitor::LinkChange lc, String netName, String ipNum) {
            Debug::TraceContextBumper ctx (SDKSTR ("Basic SSDP server - LinkMonitor callback"));
            DbgTrace (L"(lc = %d, netName=%s, ipNum=%s)", lc, netName.c_str (), ipNum.c_str ());
            if (lc == IO::Network::LinkMonitor::LinkChange::eAdded) {
                this->Restart_ ();
            }
        });
    }
    ~Rep_ ()
    {
        fLinkMonitor_.clear ();
        Thread::SuppressAbortInContext  suppressAbort;  // critical to wait til done cuz captures this
        fNotifierThread_.AbortAndWaitForDone ();
        fSearchResponderThread_.AbortAndWaitForDone ();
    }
    Sequence<Advertisement> GetAdjustedAdvertisements_ () const
    {
        if (fLocation.GetHost ().empty ()) {
            Sequence<Advertisement> revisedAdvertisements;
            URL useURL = fLocation;
            useURL.SetHost (IO::Network::GetPrimaryInternetAddress ().As<String> ());
            for (auto ai : fAdvertisements) {
                ai.fLocation = useURL.GetFullURL ();
                revisedAdvertisements.Append (ai);
            }
            return revisedAdvertisements;
        }
        else {
            return fAdvertisements;
        }
    }
    void    StartNotifier_ ()
    {
        fNotifierThread_ = Thread ([this]() {
            PeriodicNotifier l;
            l.Run (GetAdjustedAdvertisements_ (), PeriodicNotifier::FrequencyInfo ());
        });
        fNotifierThread_.SetThreadName (L"SSDP Notifier Thread");
        fNotifierThread_.Start ();
    }
    void    StartResponder_ ()
    {
        fSearchResponderThread_ = Thread ([this]() {
            SearchResponder sr;
            sr.Run (GetAdjustedAdvertisements_ ());
        });
        fNotifierThread_.SetThreadName (L"SSDP Search Responder Thread");
        fSearchResponderThread_.Start ();
    }
    void    Restart_ ()
    {
        Debug::TraceContextBumper ctx (SDKSTR ("Restarting Basic SSDP server threads"));
        {
            Thread::SuppressAbortInContext  suppressAbort;  // critical to wait til done cuz captures this
            fNotifierThread_.AbortAndWaitForDone ();
            fSearchResponderThread_.AbortAndWaitForDone ();
        }
        StartNotifier_ ();
        StartResponder_ ();
    }
    Execution::Thread                   fNotifierThread_;
    Execution::Thread                   fSearchResponderThread_;
    Optional<IO::Network::LinkMonitor>  fLinkMonitor_;          // optional so we can delete it first on shutdown (so no restart while stopping stuff)
};

/*
********************************************************************************
********************************** BasicServer *********************************
********************************************************************************
*/
BasicServer::BasicServer (const Device& d, const DeviceDescription& dd, const FrequencyInfo& fi)
    : fRep_ (new Rep_ (d, dd, fi))
{
}
<commit_msg>minor rework of optional use to accomodate more strict const rules<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#include    "../../../StroikaPreComp.h"

#include    "../../../../Foundation/Characters/Format.h"
#include    "../../../../Foundation/Characters/String_Constant.h"
#include    "../../../../Foundation/Containers/Sequence.h"
#include    "../../../../Foundation/Debug/Trace.h"
#include    "../../../../Foundation/Execution/Sleep.h"
#include    "../../../../Foundation/Execution/Thread.h"
#include    "../../../../Foundation/IO/Network/LinkMonitor.h"
#include    "../../../../Foundation/IO/Network/Socket.h"
#include    "../../../../Foundation/Streams/BasicBinaryOutputStream.h"
#include    "../../../../Foundation/Streams/TextOutputStreamBinaryAdapter.h"

#include    "../Common.h"
#include    "../Advertisement.h"
#include    "BasicServer.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::Network;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::UPnP;
using   namespace   Stroika::Frameworks::UPnP::SSDP;
using   namespace   Stroika::Frameworks::UPnP::SSDP::Server;

/*
********************************************************************************
******************************* BasicServer::Rep_ ******************************
********************************************************************************
*/
class   BasicServer::Rep_ {
public:
    Sequence<Advertisement> fAdvertisements;
    FrequencyInfo           fFrequencyInfo;
    URL                     fLocation;
    Rep_ (const Device& d, const DeviceDescription& dd, const FrequencyInfo& fi)
        : fAdvertisements ()
        , fFrequencyInfo (fi)
        , fLocation (d.fLocation)
    {
        {
            SSDP::Advertisement  dan;
            dan.fLocation = d.fLocation.GetFullURL ();
            dan.fServer = d.fServer;
            {
                dan.fTarget = kTarget_UPNPRootDevice;
                dan.fUSN = Format (L"uuid:%s::%s", d.fDeviceID.c_str (), kTarget_UPNPRootDevice.c_str ());
                fAdvertisements.Append (dan);
            }
            {
                dan.fUSN = Format (L"uuid:%s", d.fDeviceID.c_str ());
                dan.fTarget = dan.fUSN;
                fAdvertisements.Append (dan);
            }
            if (not dd.fDeviceType.empty ()) {
                dan.fUSN = Format (L"uuid:%s::%s", d.fDeviceID.c_str (), dd.fDeviceType.c_str ());
                dan.fTarget = dd.fDeviceType;
                fAdvertisements.Append (dan);
            }
        }

        StartNotifier_ ();
        StartResponder_ ();

		IO::Network::LinkMonitor	lm;
		lm.AddCallback ([this] (IO::Network::LinkMonitor::LinkChange lc, String netName, String ipNum) {
            Debug::TraceContextBumper ctx (SDKSTR ("Basic SSDP server - LinkMonitor callback"));
            DbgTrace (L"(lc = %d, netName=%s, ipNum=%s)", lc, netName.c_str (), ipNum.c_str ());
            if (lc == IO::Network::LinkMonitor::LinkChange::eAdded) {
                this->Restart_ ();
            }
        });
        fLinkMonitor_ = Optional<IO::Network::LinkMonitor> (move (lm));
#if 0
        fLinkMonitor_ = Optional<IO::Network::LinkMonitor> (move (IO::Network::LinkMonitor ()));
        fLinkMonitor_->AddCallback ([this] (IO::Network::LinkMonitor::LinkChange lc, String netName, String ipNum) {
            Debug::TraceContextBumper ctx (SDKSTR ("Basic SSDP server - LinkMonitor callback"));
            DbgTrace (L"(lc = %d, netName=%s, ipNum=%s)", lc, netName.c_str (), ipNum.c_str ());
            if (lc == IO::Network::LinkMonitor::LinkChange::eAdded) {
                this->Restart_ ();
            }
        });
#endif
    }
    ~Rep_ ()
    {
        fLinkMonitor_.clear ();
        Thread::SuppressAbortInContext  suppressAbort;  // critical to wait til done cuz captures this
        fNotifierThread_.AbortAndWaitForDone ();
        fSearchResponderThread_.AbortAndWaitForDone ();
    }
    Sequence<Advertisement> GetAdjustedAdvertisements_ () const
    {
        if (fLocation.GetHost ().empty ()) {
            Sequence<Advertisement> revisedAdvertisements;
            URL useURL = fLocation;
            useURL.SetHost (IO::Network::GetPrimaryInternetAddress ().As<String> ());
            for (auto ai : fAdvertisements) {
                ai.fLocation = useURL.GetFullURL ();
                revisedAdvertisements.Append (ai);
            }
            return revisedAdvertisements;
        }
        else {
            return fAdvertisements;
        }
    }
    void    StartNotifier_ ()
    {
        fNotifierThread_ = Thread ([this]() {
            PeriodicNotifier l;
            l.Run (GetAdjustedAdvertisements_ (), PeriodicNotifier::FrequencyInfo ());
        });
        fNotifierThread_.SetThreadName (L"SSDP Notifier Thread");
        fNotifierThread_.Start ();
    }
    void    StartResponder_ ()
    {
        fSearchResponderThread_ = Thread ([this]() {
            SearchResponder sr;
            sr.Run (GetAdjustedAdvertisements_ ());
        });
        fNotifierThread_.SetThreadName (L"SSDP Search Responder Thread");
        fSearchResponderThread_.Start ();
    }
    void    Restart_ ()
    {
        Debug::TraceContextBumper ctx (SDKSTR ("Restarting Basic SSDP server threads"));
        {
            Thread::SuppressAbortInContext  suppressAbort;  // critical to wait til done cuz captures this
            fNotifierThread_.AbortAndWaitForDone ();
            fSearchResponderThread_.AbortAndWaitForDone ();
        }
        StartNotifier_ ();
        StartResponder_ ();
    }
    Execution::Thread                   fNotifierThread_;
    Execution::Thread                   fSearchResponderThread_;
    Optional<IO::Network::LinkMonitor>  fLinkMonitor_;          // optional so we can delete it first on shutdown (so no restart while stopping stuff)
};

/*
********************************************************************************
********************************** BasicServer *********************************
********************************************************************************
*/
BasicServer::BasicServer (const Device& d, const DeviceDescription& dd, const FrequencyInfo& fi)
    : fRep_ (new Rep_ (d, dd, fi))
{
}
<|endoftext|>


<commit_before>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef TransporterFacade_H
#define TransporterFacade_H

#include <kernel_types.h>
#include <ndb_limits.h>
#include <NdbThread.h>
#include <TransporterRegistry.hpp>
#include <NdbMutex.h>
#include "DictCache.hpp"
#include <BlockNumbers.h>

class ClusterMgr;
class ArbitMgr;
class IPCConfig;
struct ndb_mgm_configuration;
class ConfigRetriever;

class Ndb;
class NdbApiSignal;

typedef void (* ExecuteFunction)(void *, NdbApiSignal *, LinearSectionPtr ptr[3]);
typedef void (* NodeStatusFunction)(void *, Uint32, bool nodeAlive, bool nfComplete);

extern "C" {
  void* runSendRequest_C(void*);
  void* runReceiveResponse_C(void*);
  void atexit_stop_instance();
}

/**
 * Max number of Ndb objects in different threads.
 * (Ndb objects should not be shared by different threads.)
 */
class TransporterFacade
{
public:
  TransporterFacade();
  virtual ~TransporterFacade();
  bool init(Uint32, const ndb_mgm_configuration *);

  static TransporterFacade* instance();
  int start_instance(int, const ndb_mgm_configuration*);
  static void stop_instance();

  /**
   * Register this block for sending/receiving signals
   * @return BlockNumber or -1 for failure
   */
  int open(void* objRef, ExecuteFunction, NodeStatusFunction);

  // Close this block number
  int close(BlockNumber blockNumber, Uint64 trans_id);

  // Only sends to nodes which are alive
  int sendSignal(NdbApiSignal * signal, NodeId nodeId);
  int sendSignal(NdbApiSignal*, NodeId,
		 LinearSectionPtr ptr[3], Uint32 secs);
  int sendFragmentedSignal(NdbApiSignal*, NodeId,
			   LinearSectionPtr ptr[3], Uint32 secs);

  // Is node available for running transactions
  bool   get_node_alive(NodeId nodeId) const;
  bool   get_node_stopping(NodeId nodeId) const;
  bool   getIsDbNode(NodeId nodeId) const;
  bool   getIsNodeSendable(NodeId nodeId) const;
  Uint32 getNodeGrp(NodeId nodeId) const;
  Uint32 getNodeSequence(NodeId nodeId) const;

  // Is there space in sendBuffer to send messages
  bool   check_send_size(Uint32 node_id, Uint32 send_size);

  // My own processor id
  NodeId ownId() const;

  void connected();

  void doConnect(int NodeId);
  void reportConnected(int NodeId);
  void doDisconnect(int NodeId);
  void reportDisconnected(int NodeId);

  NodeId get_an_alive_node();
  void ReportNodeAlive(NodeId nodeId);
  void ReportNodeDead(NodeId nodeId);
  void ReportNodeFailureComplete(NodeId nodeId);

  void lock_mutex();
  void unlock_mutex();

  // Improving the API performance
  void forceSend(Uint32 block_number);
  void checkForceSend(Uint32 block_number);

  // Close this block number
  int close_local(BlockNumber blockNumber);

  // Scan batch configuration parameters
  Uint32 get_scan_batch_size();
  Uint32 get_batch_byte_size();
  Uint32 get_batch_size();

private:
  /**
   * Send a signal unconditional of node status (used by ClusterMgr)
   */
  friend class ClusterMgr;
  friend class ArbitMgr;
  friend class MgmtSrvr;
  friend class SignalSender;
  friend class GrepPS;
  friend class ExtSender; ///< @todo Hack to be able to sendSignalUnCond
  friend class GrepSS;
  friend class Ndb;
  friend class Ndb_cluster_connection;

  int sendSignalUnCond(NdbApiSignal *, NodeId nodeId);

  bool isConnected(NodeId aNodeId);
  void doStop();

  TransporterRegistry* theTransporterRegistry;
  SocketServer m_socket_server;
  int sendPerformedLastInterval;
  int theOwnId;

  NodeId theStartNodeId;

  ClusterMgr* theClusterMgr;
  ArbitMgr* theArbitMgr;

  // Improving the API response time
  int checkCounter;
  Uint32 currentSendLimit;

  void calculateSendLimit();

  // Scan batch configuration parameters
  Uint32 m_scan_batch_size;
  Uint32 m_batch_byte_size;
  Uint32 m_batch_size;

  // Declarations for the receive and send thread
  int  theStopReceive;

  void threadMainSend(void);
  NdbThread* theSendThread;
  void threadMainReceive(void);
  NdbThread* theReceiveThread;

  friend void* runSendRequest_C(void*);
  friend void* runReceiveResponse_C(void*);
  friend void atexit_stop_instance();

  /**
   * Block number handling
   */
public:
  STATIC_CONST( MAX_NO_THREADS = 4711 );
private:

  struct ThreadData {
    STATIC_CONST( ACTIVE = (1 << 16) | 1 );
    STATIC_CONST( INACTIVE = (1 << 16) );
    STATIC_CONST( END_OF_LIST = MAX_NO_THREADS + 1 );

    ThreadData(Uint32 initialSize = 32);

    /**
     * Split "object" into 3 list
     *   This to improve locality
     *   when iterating over lists
     */
    struct Object_Execute {
      void * m_object;
      ExecuteFunction m_executeFunction;
    };
    struct NodeStatus_NextFree {
      NodeStatusFunction m_statusFunction;
    };

    Uint32 m_firstFree;
    Vector<Uint32> m_statusNext;
    Vector<Object_Execute> m_objectExecute;
    Vector<NodeStatusFunction> m_statusFunction;

    int open(void* objRef, ExecuteFunction, NodeStatusFunction);
    int close(int number);
    void expand(Uint32 size);

    inline Object_Execute get(Uint16 blockNo) const {
      blockNo -= MIN_API_BLOCK_NO;
      if(blockNo < m_objectExecute.size()){
	return m_objectExecute[blockNo];
      }
      Object_Execute oe = { 0, 0 };
      return oe;
    }

    /**
     * Is the block number used currently
     */
    inline bool getInUse(Uint16 index) const {
      return (m_statusNext[index] & (1 << 16)) != 0;
    }
  } m_threads;

  Uint32 m_max_trans_id;
  Uint32 m_fragmented_signal_id;

  /**
   * execute function
   */
  friend void execute(void * callbackObj, SignalHeader * const header,
                      Uint8 prio,
                      Uint32 * const theData, LinearSectionPtr ptr[3]);

public:
  NdbMutex* theMutexPtr;
private:
  static TransporterFacade* theFacadeInstance;

public:
  GlobalDictCache m_globalDictCache;
};

inline
TransporterFacade*
TransporterFacade::instance()
{
  return theFacadeInstance;
}

inline
void
TransporterFacade::lock_mutex()
{
  NdbMutex_Lock(theMutexPtr);
}

inline
void
TransporterFacade::unlock_mutex()
{
  NdbMutex_Unlock(theMutexPtr);
}

#include "ClusterMgr.hpp"

inline
bool
TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size)
{
  return true;
}

inline
bool
TransporterFacade::getIsDbNode(NodeId n) const {
  return
    theClusterMgr->getNodeInfo(n).defined &&
    theClusterMgr->getNodeInfo(n).m_info.m_type == NodeInfo::DB;
}

inline
Uint32
TransporterFacade::getNodeGrp(NodeId n) const {
  return theClusterMgr->getNodeInfo(n).m_state.nodeGroup;
}

inline
bool
TransporterFacade::get_node_alive(NodeId n) const {

  const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
  return node.m_alive;
}

inline
bool
TransporterFacade::get_node_stopping(NodeId n) const {
  const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
  return ((node.m_state.startLevel == NodeState::SL_STOPPING_1) ||
          (node.m_state.startLevel == NodeState::SL_STOPPING_2));
}

inline
bool
TransporterFacade::getIsNodeSendable(NodeId n) const {
  const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
  const Uint32 startLevel = node.m_state.startLevel;

  if (node.m_info.m_type == NodeInfo::DB) {
    if(node.m_state.singleUserMode &&
       ownId() == node.m_state.singleUserApi) {
      return (node.compatible &&
              (node.m_state.startLevel == NodeState::SL_STOPPING_1 ||
               node.m_state.startLevel == NodeState::SL_STARTED ||
               node.m_state.startLevel == NodeState::SL_SINGLEUSER));
      }
      else
        return node.compatible && (startLevel == NodeState::SL_STARTED ||
                                 startLevel == NodeState::SL_STOPPING_1);
  } else if (node.m_info.m_type == NodeInfo::REP) {
    /**
     * @todo Check that REP node actually has received API_REG_REQ
     */
    return node.compatible;
  } else {
    ndbout_c("TransporterFacade::getIsNodeSendable: Illegal node type: "
             "%d of node: %d",
             node.m_info.m_type, n);
    abort();
    return false; // to remove compiler warning
  }
}

inline
Uint32
TransporterFacade::getNodeSequence(NodeId n) const {
  return theClusterMgr->getNodeInfo(n).m_info.m_connectCount;
}

inline
Uint32
TransporterFacade::get_scan_batch_size() {
  return m_scan_batch_size;
}

inline
Uint32
TransporterFacade::get_batch_byte_size() {
  return m_batch_byte_size;
}

inline
Uint32
TransporterFacade::get_batch_size() {
  return m_batch_size;
}

#endif // TransporterFacade_H
<commit_msg>Correct and move comment<commit_after>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef TransporterFacade_H
#define TransporterFacade_H

#include <kernel_types.h>
#include <ndb_limits.h>
#include <NdbThread.h>
#include <TransporterRegistry.hpp>
#include <NdbMutex.h>
#include "DictCache.hpp"
#include <BlockNumbers.h>

class ClusterMgr;
class ArbitMgr;
class IPCConfig;
struct ndb_mgm_configuration;
class ConfigRetriever;

class Ndb;
class NdbApiSignal;

typedef void (* ExecuteFunction)(void *, NdbApiSignal *, LinearSectionPtr ptr[3]);
typedef void (* NodeStatusFunction)(void *, Uint32, bool nodeAlive, bool nfComplete);

extern "C" {
  void* runSendRequest_C(void*);
  void* runReceiveResponse_C(void*);
  void atexit_stop_instance();
}

class TransporterFacade
{
public:
  TransporterFacade();
  virtual ~TransporterFacade();
  bool init(Uint32, const ndb_mgm_configuration *);

  static TransporterFacade* instance();
  int start_instance(int, const ndb_mgm_configuration*);
  static void stop_instance();

  /**
   * Register this block for sending/receiving signals
   * @return BlockNumber or -1 for failure
   */
  int open(void* objRef, ExecuteFunction, NodeStatusFunction);

  // Close this block number
  int close(BlockNumber blockNumber, Uint64 trans_id);

  // Only sends to nodes which are alive
  int sendSignal(NdbApiSignal * signal, NodeId nodeId);
  int sendSignal(NdbApiSignal*, NodeId,
		 LinearSectionPtr ptr[3], Uint32 secs);
  int sendFragmentedSignal(NdbApiSignal*, NodeId,
			   LinearSectionPtr ptr[3], Uint32 secs);

  // Is node available for running transactions
  bool   get_node_alive(NodeId nodeId) const;
  bool   get_node_stopping(NodeId nodeId) const;
  bool   getIsDbNode(NodeId nodeId) const;
  bool   getIsNodeSendable(NodeId nodeId) const;
  Uint32 getNodeGrp(NodeId nodeId) const;
  Uint32 getNodeSequence(NodeId nodeId) const;

  // Is there space in sendBuffer to send messages
  bool   check_send_size(Uint32 node_id, Uint32 send_size);

  // My own processor id
  NodeId ownId() const;

  void connected();

  void doConnect(int NodeId);
  void reportConnected(int NodeId);
  void doDisconnect(int NodeId);
  void reportDisconnected(int NodeId);

  NodeId get_an_alive_node();
  void ReportNodeAlive(NodeId nodeId);
  void ReportNodeDead(NodeId nodeId);
  void ReportNodeFailureComplete(NodeId nodeId);

  void lock_mutex();
  void unlock_mutex();

  // Improving the API performance
  void forceSend(Uint32 block_number);
  void checkForceSend(Uint32 block_number);

  // Close this block number
  int close_local(BlockNumber blockNumber);

  // Scan batch configuration parameters
  Uint32 get_scan_batch_size();
  Uint32 get_batch_byte_size();
  Uint32 get_batch_size();

private:
  /**
   * Send a signal unconditional of node status (used by ClusterMgr)
   */
  friend class ClusterMgr;
  friend class ArbitMgr;
  friend class MgmtSrvr;
  friend class SignalSender;
  friend class GrepPS;
  friend class ExtSender; ///< @todo Hack to be able to sendSignalUnCond
  friend class GrepSS;
  friend class Ndb;
  friend class Ndb_cluster_connection;

  int sendSignalUnCond(NdbApiSignal *, NodeId nodeId);

  bool isConnected(NodeId aNodeId);
  void doStop();

  TransporterRegistry* theTransporterRegistry;
  SocketServer m_socket_server;
  int sendPerformedLastInterval;
  int theOwnId;

  NodeId theStartNodeId;

  ClusterMgr* theClusterMgr;
  ArbitMgr* theArbitMgr;

  // Improving the API response time
  int checkCounter;
  Uint32 currentSendLimit;

  void calculateSendLimit();

  // Scan batch configuration parameters
  Uint32 m_scan_batch_size;
  Uint32 m_batch_byte_size;
  Uint32 m_batch_size;

  // Declarations for the receive and send thread
  int  theStopReceive;

  void threadMainSend(void);
  NdbThread* theSendThread;
  void threadMainReceive(void);
  NdbThread* theReceiveThread;

  friend void* runSendRequest_C(void*);
  friend void* runReceiveResponse_C(void*);
  friend void atexit_stop_instance();

  /**
   * Block number handling
   */
public:
  /**
   * Max number of Ndb objects.
   * (Ndb objects should not be shared by different threads.)
   */
  STATIC_CONST( MAX_NO_THREADS = 4711 );
private:

  struct ThreadData {
    STATIC_CONST( ACTIVE = (1 << 16) | 1 );
    STATIC_CONST( INACTIVE = (1 << 16) );
    STATIC_CONST( END_OF_LIST = MAX_NO_THREADS + 1 );

    ThreadData(Uint32 initialSize = 32);

    /**
     * Split "object" into 3 list
     *   This to improve locality
     *   when iterating over lists
     */
    struct Object_Execute {
      void * m_object;
      ExecuteFunction m_executeFunction;
    };
    struct NodeStatus_NextFree {
      NodeStatusFunction m_statusFunction;
    };

    Uint32 m_firstFree;
    Vector<Uint32> m_statusNext;
    Vector<Object_Execute> m_objectExecute;
    Vector<NodeStatusFunction> m_statusFunction;

    int open(void* objRef, ExecuteFunction, NodeStatusFunction);
    int close(int number);
    void expand(Uint32 size);

    inline Object_Execute get(Uint16 blockNo) const {
      blockNo -= MIN_API_BLOCK_NO;
      if(blockNo < m_objectExecute.size()){
	return m_objectExecute[blockNo];
      }
      Object_Execute oe = { 0, 0 };
      return oe;
    }

    /**
     * Is the block number used currently
     */
    inline bool getInUse(Uint16 index) const {
      return (m_statusNext[index] & (1 << 16)) != 0;
    }
  } m_threads;

  Uint32 m_max_trans_id;
  Uint32 m_fragmented_signal_id;

  /**
   * execute function
   */
  friend void execute(void * callbackObj, SignalHeader * const header,
                      Uint8 prio,
                      Uint32 * const theData, LinearSectionPtr ptr[3]);

public:
  NdbMutex* theMutexPtr;
private:
  static TransporterFacade* theFacadeInstance;

public:
  GlobalDictCache m_globalDictCache;
};

inline
TransporterFacade*
TransporterFacade::instance()
{
  return theFacadeInstance;
}

inline
void
TransporterFacade::lock_mutex()
{
  NdbMutex_Lock(theMutexPtr);
}

inline
void
TransporterFacade::unlock_mutex()
{
  NdbMutex_Unlock(theMutexPtr);
}

#include "ClusterMgr.hpp"

inline
bool
TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size)
{
  return true;
}

inline
bool
TransporterFacade::getIsDbNode(NodeId n) const {
  return
    theClusterMgr->getNodeInfo(n).defined &&
    theClusterMgr->getNodeInfo(n).m_info.m_type == NodeInfo::DB;
}

inline
Uint32
TransporterFacade::getNodeGrp(NodeId n) const {
  return theClusterMgr->getNodeInfo(n).m_state.nodeGroup;
}

inline
bool
TransporterFacade::get_node_alive(NodeId n) const {

  const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
  return node.m_alive;
}

inline
bool
TransporterFacade::get_node_stopping(NodeId n) const {
  const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
  return ((node.m_state.startLevel == NodeState::SL_STOPPING_1) ||
          (node.m_state.startLevel == NodeState::SL_STOPPING_2));
}

inline
bool
TransporterFacade::getIsNodeSendable(NodeId n) const {
  const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
  const Uint32 startLevel = node.m_state.startLevel;

  if (node.m_info.m_type == NodeInfo::DB) {
    if(node.m_state.singleUserMode &&
       ownId() == node.m_state.singleUserApi) {
      return (node.compatible &&
              (node.m_state.startLevel == NodeState::SL_STOPPING_1 ||
               node.m_state.startLevel == NodeState::SL_STARTED ||
               node.m_state.startLevel == NodeState::SL_SINGLEUSER));
      }
      else
        return node.compatible && (startLevel == NodeState::SL_STARTED ||
                                 startLevel == NodeState::SL_STOPPING_1);
  } else if (node.m_info.m_type == NodeInfo::REP) {
    /**
     * @todo Check that REP node actually has received API_REG_REQ
     */
    return node.compatible;
  } else {
    ndbout_c("TransporterFacade::getIsNodeSendable: Illegal node type: "
             "%d of node: %d",
             node.m_info.m_type, n);
    abort();
    return false; // to remove compiler warning
  }
}

inline
Uint32
TransporterFacade::getNodeSequence(NodeId n) const {
  return theClusterMgr->getNodeInfo(n).m_info.m_connectCount;
}

inline
Uint32
TransporterFacade::get_scan_batch_size() {
  return m_scan_batch_size;
}

inline
Uint32
TransporterFacade::get_batch_byte_size() {
  return m_batch_byte_size;
}

inline
Uint32
TransporterFacade::get_batch_size() {
  return m_batch_size;
}

#endif // TransporterFacade_H
<|endoftext|>


<commit_before>//____________________________________________________________________________
/*!

\class    GasTPCGun: Not the classical way to run a particle gun.
                     The way the simulation is setup is much easier to
                     generate each particle's kinematics and then propagate
                     into geant

\brief    Program to fire single particles using particle gun.
	  Only tracking, no flux or event generation

\author	  Tom Stainer <tstainer \at liv.ac.uk>
          University of Liverpool

\author	  Georgios Christodoulou <georgios at hep.ph.liv.ac.uk>
          University of Liverpool

\created  Oct 2014
\last update Jun 2015
*/
//____________________________________________________________________________
#include "GasTPCProcessorManager.hh"
#include "GeometryLoader.hh"
//#include "ParticleGunProcessor.hh"
#include "Geant4TrackingAlgorithm.hh"
#include "GasTPCParticleGun.hh"

#include "TXMLEngine.h"
#include "Messenger.hh"

using namespace util;

int main(int argc, char ** argv) {

  // Load the xml file
  std::string datacard   = "";
  std::string outputfile = "PGData.root";
  int nentries = 100;
  for(int iArg = 1; iArg < argc; iArg++) {
    if((!strcasecmp(argv[iArg],"-d"))||(!strcasecmp(argv[iArg],"-datacard"))) {
      datacard = argv[++iArg] ;
    }
    if((!strcasecmp(argv[iArg],"-n"))) {
      nentries = atoi(argv[++iArg]);
      std::cout << "INFO::Generating " << nentries << " events." << std::endl;
    }
    if((!strcasecmp(argv[iArg],"-o"))||(!strcasecmp(argv[iArg],"-output"))) {
      outputfile = argv[++iArg] ;
    }
  }

  // Load the xml file
  const char* gastpc_dir = getenv("GasTPC");
  if(datacard == "")
    datacard = "GeantSimulation.xml";
  std::string fdatacard = string(gastpc_dir) + "/src/config/" + datacard;

  ReadDatacard(fdatacard);

  // Define the input tree
  TTree *pg = new TTree("pg","pg");

  double Px,Py,Pz,E,X,Y,Z,M;
  int pdg;

  pg->Branch("Px",    &Px,  "Px/D");
  pg->Branch("Py",    &Py,  "Py/D");
  pg->Branch("Pz",    &Pz,  "Pz/D");
  pg->Branch("E",     &E,   "E/D");
  pg->Branch("X",     &X,   "X/D");
  pg->Branch("Y",     &Y,   "Y/D");
  pg->Branch("Z",     &Z,   "Z/D");
  pg->Branch("M",     &M,   "M/D");
  pg->Branch("pdg",   &pdg, "pdg/I");

  // Fill the tree
  for(int i=0; i< nentries; i++){
    // Determine the mass
    double fMass = 105.66; // Muon as default
    pdg = fPDG;
    if(pdg == 22)
      fMass = 0;
    else if(abs(pdg) == 11)
      fMass = 0.511;
    else if(abs(pdg) == 13)
      fMass = 105.66;
    else if(abs(pdg) == 211)
      fMass = 139.57;
    else if(abs(pdg) == 321)
      fMass = 493.67;
    else if(abs(pdg) == 2212)
      fMass = 938.27;
    else if(abs(pdg) == 2112)
      fMass = 939.57;
    else{
      cout << "Choose the correct pdg to simulate. 11,-11,13,-13,22,211,-211,321,-321,2212,2112" << endl;
      break;
    }

    //determine monoenergetic or energy spectrum
    if(fMinEnergy == fMaxEnergy){
      E = fMaxEnergy;
    }
    else{
      TRandom rand;
      rand.SetSeed(i+999);
      if(fgauss == 0)
	E = rand.Uniform(fMinEnergy,fMaxEnergy);
      else
	E = rand.Gaus(fMaxEnergy);
    }

    //if all 3 momentum are 0 then indicates to use Gaussian
    Px = fMomentumX;
    Py = fMomentumY;
    Pz = fMomentumZ;
    while( (Px == 0) && (Py == 0 ) && ( Pz == 0) ){
      TRandom3 rand;
      rand.SetSeed(i+999);
      Px = rand.Gaus();
      Py = rand.Gaus();
      Pz = rand.Gaus();
    }

    //normalise momentum to unit vectors and multiply by energy
    double Mom = TMath::Sqrt( Px*Px + Py*Py + Pz*Pz);
    //turn them into unit vectors and multiply by true momentum
    //M = fMass;
    Px *= (TMath::Sqrt( E*E - M*M ))/Mom;
    Py *= (TMath::Sqrt( E*E - M*M ))/Mom;
    Pz *= (TMath::Sqrt( E*E - M*M ))/Mom;

    X = fPositionX;
    Y = fPositionY;
    Z = fPositionZ;
    //pdg = fPDG;

    pg->Fill();
  }

  //try {
  // Create Processor Manage.
  GasTPCProcessorManager manager;
  manager.initialize(outputfile,fTrackingVerbose);

  //Initiate geometry loader
  //GeometryLoader * geomLoader = new GeometryLoader();

  // Initialize your processors here. The processors will define
  // default values for all runtime parameters.
  //ParticleGunProcessor   *g4tracking = new ParticleGunProcessor(geomLoader);

  // Get command line arguments if any.
  // This will modify the default values for the runtime parameters.
  //manager.getRunTimeArguments(argc, argv);
  //manager.loadDataCards();

  // Initialize your processors here. The processors will define
  // default values for all runtime parameters.
  LoadNuEventProcessor     *eventLoader  = new LoadNuEventProcessor();
  eventLoader->initialize("particlegun",pg,fGeometryFile,1);
  if(nentries > 0)
    eventLoader->setNEvents(nentries);

  Geant4TrackingAlgorithm *g4trackingalg = new Geant4TrackingAlgorithm(fGeometryFile,fSimTargetVolume);
  //g4trackingalg->setGeometryFile(fGeometryFile);
  //g4trackingalg->setTargetVolumeName(fSimTargetVolume);
  g4trackingalg->setPhysicsList(fEMPhysicsList,fHadPhysicsList);
  g4trackingalg->setMagneticField(fMagneticFieldStrength);
  g4trackingalg->setEnergyCut(fMinEnergyCut);
  g4trackingalg->setDefaultCut(fGammaCut);
  g4trackingalg->setElectronCut(fElectronCut);
  g4trackingalg->setPositronCut(fPositronCut);
  g4trackingalg->setGammaCut(fGammaCut);
  g4trackingalg->setNeutronCut(fNeutronCut);
  g4trackingalg->setVerbose(fTrackingVerbose);
  //g4trackingalg->doVis(false);
  //g4trackingalg->doParticleGun(false);

  Geant4TrackingProcessor  *g4tracking   = new Geant4TrackingProcessor(g4trackingalg);
  /*
  ParticleGunProcessor   *g4tracking = new ParticleGunProcessor(g4trackingalg);
  g4tracking->SetPosition(fPositionX,fPositionY,fPositionZ);
  g4tracking->SetMomentum(fMomentumX,fMomentumY,fMomentumZ);
  g4tracking->SetMinMaxEnergy(fMinEnergy,fMaxEnergy);
  g4tracking->SetMass(fMass);
  g4tracking->SetPdg(fPDG);
  */
  // Now add your processors to the manages.
  manager.addProcessor(eventLoader);
  manager.addProcessor(g4tracking);

  //reinitiate the geometry loader
  //geomLoader->initialize(eventLoader->get);

  manager.printToStream(cout);

  // Run your processors.
  manager.go();

  // Store the result.
  manager.write();

  //close the geometry
  //geomLoader->close();
  /*
    } catch (GasTPCException e) {
    std::cout << e.GetLocation() << std::endl;
    std::cout << e.GetDescription() << std::endl;
    return 1;
    }
  */
  return 0;
}

void ReadDatacard(std::string datacard){

  LOG("GeometryConstruction",pNOTICE) << "Reading configuration from XML file [" << datacard << "]";

  TXMLEngine* xml = new TXMLEngine();
  XMLDocPointer_t xmldoc = xml->ParseFile(datacard.c_str());
  if (xmldoc==0) {
    std::cerr << "Exp >> " << "Can not parse input: " << datacard << std::endl;
    delete xml;
    return;
  }
  XMLNodePointer_t root_node = xml->DocGetRootElement(xmldoc);
  fGeometryFile          = util::XML2String(xml,root_node,"GeometryFile");
  fSimTargetVolume       = util::XML2String(xml,root_node,"SimTargetVolume");
  fMinEnergyCut          = util::XML2Dbl(xml,root_node,"ParticleThresholds/MinEnergyCut");
  fGammaCut              = util::XML2Dbl(xml,root_node,"ParticleThresholds/GammaCut");
  fElectronCut           = util::XML2Dbl(xml,root_node,"ParticleThresholds/ElectronCut");
  fPositronCut           = util::XML2Dbl(xml,root_node,"ParticleThresholds/PositronCut");
  fNeutronCut            = util::XML2Dbl(xml,root_node,"ParticleThresholds/NeutronCut");
  fRunVisMacro           = util::XML2Bool(xml,root_node,"RunVisMacro");
  fPhysicsList           = util::XML2String(xml,root_node,"PhysicsList");
  fEMPhysicsList         = util::XML2String(xml,root_node,"EMPhysicsList");
  fHadPhysicsList        = util::XML2String(xml,root_node,"HadPhysicsList");
  fMagneticFieldStrength = util::XML2Dbl(xml,root_node,"MagneticFieldStrength");
  fTrackingVerbose       = (int)util::XML2Dbl(xml,root_node,"TrackingVerbose");
  // Particle gun options
  fPositionX             = util::XML2Dbl(xml,root_node,"ParticleGun/PositionX");
  fPositionY             = util::XML2Dbl(xml,root_node,"ParticleGun/PositionY");
  fPositionZ             = util::XML2Dbl(xml,root_node,"ParticleGun/PositionZ");
  fMomentumX             = util::XML2Dbl(xml,root_node,"ParticleGun/MomentumX");
  fMomentumY             = util::XML2Dbl(xml,root_node,"ParticleGun/MomentumY");
  fMomentumZ             = util::XML2Dbl(xml,root_node,"ParticleGun/MomentumZ");
  fMinEnergy             = util::XML2Dbl(xml,root_node,"ParticleGun/MinEnergy");
  fMaxEnergy             = util::XML2Dbl(xml,root_node,"ParticleGun/MaxEnergy");
  fPDG                   = util::XML2Dbl(xml,root_node,"ParticleGun/PDG");
  fgauss                 = util::XML2Dbl(xml,root_node,"ParticleGun/Gauss");
}

<commit_msg>Necessary changes to run the particle gun.<commit_after>//____________________________________________________________________________
/*!

\class    GasTPCGun: Not the classical way to run a particle gun.
                     The way the simulation is setup is much easier to
                     generate each particle's kinematics and then propagate
                     into geant

\brief    Program to fire single particles using particle gun.
	  Only tracking, no flux or event generation

\author	  Tom Stainer <tstainer \at liv.ac.uk>
          University of Liverpool

\author	  Georgios Christodoulou <georgios at hep.ph.liv.ac.uk>
          University of Liverpool

\created  Oct 2014
\last update Jun 2015
*/
//____________________________________________________________________________
#include "GasTPCProcessorManager.hh"
#include "GeometryLoader.hh"
//#include "ParticleGunProcessor.hh"
#include "Geant4TrackingAlgorithm.hh"
#include "GasTPCParticleGun.hh"

#include "TXMLEngine.h"
#include "Messenger.hh"

using namespace util;

int main(int argc, char ** argv) {

  // Load the xml file
  std::string datacard   = "";
  std::string outputfile = "PGData.root";
  int nentries = 100;
  for(int iArg = 1; iArg < argc; iArg++) {
    if((!strcasecmp(argv[iArg],"-d"))||(!strcasecmp(argv[iArg],"-datacard"))) {
      datacard = argv[++iArg] ;
    }
    if((!strcasecmp(argv[iArg],"-n"))) {
      nentries = atoi(argv[++iArg]);
      std::cout << "INFO::Generating " << nentries << " events." << std::endl;
    }
    if((!strcasecmp(argv[iArg],"-o"))||(!strcasecmp(argv[iArg],"-output"))) {
      outputfile = argv[++iArg] ;
    }
  }

  // Load the xml file
  const char* gastpc_dir = getenv("GasTPC");
  if(datacard == "")
    datacard = "GeantSimulationPG.xml";
  std::string fdatacard = string(gastpc_dir) + "/src/config/" + datacard;

  ReadDatacard(fdatacard);

  if(fGeometryFile == "")
    fGeometryFile = "site.gdml";
  std::string fgeofile = string(gastpc_dir) + "/src/config/" + fGeometryFile;
  std::cout << "INFO::Geometry file :: " << fgeofile << std::endl;

  // Define the input tree
  TTree *pg = new TTree("pg","pg");

  double Px,Py,Pz,E,X,Y,Z,M;
  int pdg;

  pg->Branch("Px",    &Px,  "Px/D");
  pg->Branch("Py",    &Py,  "Py/D");
  pg->Branch("Pz",    &Pz,  "Pz/D");
  pg->Branch("E",     &E,   "E/D");
  pg->Branch("X",     &X,   "X/D");
  pg->Branch("Y",     &Y,   "Y/D");
  pg->Branch("Z",     &Z,   "Z/D");
  pg->Branch("M",     &M,   "M/D");
  pg->Branch("pdg",   &pdg, "pdg/I");

  // Fill the tree
  for(int i=0; i< nentries; i++){
    // Determine the mass
    double fMass = 105.66; // Muon as default
    pdg = fPDG;
    if(pdg == 22)
      fMass = 0;
    else if(abs(pdg) == 11)
      fMass = 0.511;
    else if(abs(pdg) == 13)
      fMass = 105.66;
    else if(abs(pdg) == 211)
      fMass = 139.57;
    else if(abs(pdg) == 321)
      fMass = 493.67;
    else if(abs(pdg) == 2212)
      fMass = 938.27;
    else if(abs(pdg) == 2112)
      fMass = 939.57;
    else{
      cout << "ERROR::Choose the correct pdg to simulate. 11,-11,13,-13,22,211,-211,321,-321,2212,2112" << endl;
      break;
    }

    //determine monoenergetic or energy spectrum
    if(fMinEnergy == fMaxEnergy){
      E = fMaxEnergy;
    }
    else{
      TRandom rand;
      rand.SetSeed(i+999);
      if(fgauss == 0)
	E = rand.Uniform(fMinEnergy,fMaxEnergy);
      else
	E = rand.Gaus(fMaxEnergy);
    }

    //if all 3 momentum are 0 then indicates to use Gaussian
    Px = fMomentumX;
    Py = fMomentumY;
    Pz = fMomentumZ;
    while( (Px == 0) && (Py == 0 ) && ( Pz == 0) ){
      TRandom3 rand;
      rand.SetSeed(i+999);
      Px = rand.Gaus();
      Py = rand.Gaus();
      Pz = rand.Gaus();
    }

    //normalise momentum to unit vectors and multiply by energy
    double Mom = TMath::Sqrt( Px*Px + Py*Py + Pz*Pz);
    //turn them into unit vectors and multiply by true momentum
    //M = fMass;
    Px *= (TMath::Sqrt( E*E - M*M ))/Mom;
    Py *= (TMath::Sqrt( E*E - M*M ))/Mom;
    Pz *= (TMath::Sqrt( E*E - M*M ))/Mom;

    X = fPositionX;
    Y = fPositionY;
    Z = fPositionZ;
    //pdg = fPDG;

    pg->Fill();
  }

  //try {
  // Create Processor Manage.
  GasTPCProcessorManager manager;
  manager.initialize(outputfile,fTrackingVerbose);

  //Initiate geometry loader
  //GeometryLoader * geomLoader = new GeometryLoader();

  // Initialize your processors here. The processors will define
  // default values for all runtime parameters.
  //ParticleGunProcessor   *g4tracking = new ParticleGunProcessor(geomLoader);

  // Get command line arguments if any.
  // This will modify the default values for the runtime parameters.
  //manager.getRunTimeArguments(argc, argv);
  //manager.loadDataCards();

  // Initialize your processors here. The processors will define
  // default values for all runtime parameters.
  LoadNuEventProcessor     *eventLoader  = new LoadNuEventProcessor();
  eventLoader->initialize("particlegun",pg,fgeofile,1);
  if(nentries > 0)
    eventLoader->setNEvents(nentries);

  Geant4TrackingAlgorithm *g4trackingalg = new Geant4TrackingAlgorithm(fgeofile,fSimTargetVolume);
  //g4trackingalg->setGeometryFile(fGeometryFile);
  //g4trackingalg->setTargetVolumeName(fSimTargetVolume);
  g4trackingalg->setPhysicsList(fEMPhysicsList,fHadPhysicsList);
  g4trackingalg->setMagneticField(fMagneticFieldStrength);
  g4trackingalg->setEnergyCut(fMinEnergyCut);
  g4trackingalg->setDefaultCut(fGammaCut);
  g4trackingalg->setElectronCut(fElectronCut);
  g4trackingalg->setPositronCut(fPositronCut);
  g4trackingalg->setGammaCut(fGammaCut);
  g4trackingalg->setNeutronCut(fNeutronCut);
  g4trackingalg->setVerbose(fTrackingVerbose);
  //g4trackingalg->doVis(false);
  //g4trackingalg->doParticleGun(false);

  Geant4TrackingProcessor  *g4tracking   = new Geant4TrackingProcessor(g4trackingalg);
  /*
  ParticleGunProcessor   *g4tracking = new ParticleGunProcessor(g4trackingalg);
  g4tracking->SetPosition(fPositionX,fPositionY,fPositionZ);
  g4tracking->SetMomentum(fMomentumX,fMomentumY,fMomentumZ);
  g4tracking->SetMinMaxEnergy(fMinEnergy,fMaxEnergy);
  g4tracking->SetMass(fMass);
  g4tracking->SetPdg(fPDG);
  */
  // Now add your processors to the manages.
  manager.addProcessor(eventLoader);
  manager.addProcessor(g4tracking);

  //reinitiate the geometry loader
  //geomLoader->initialize(eventLoader->get);

  manager.printToStream(cout);

  // Run your processors.
  manager.go();

  // Store the result.
  manager.write();

  //close the geometry
  //geomLoader->close();
  /*
    } catch (GasTPCException e) {
    std::cout << e.GetLocation() << std::endl;
    std::cout << e.GetDescription() << std::endl;
    return 1;
    }
  */
  return 0;
}

void ReadDatacard(std::string datacard){

  LOG("GeometryConstruction",pNOTICE) << "Reading configuration from XML file [" << datacard << "]";

  TXMLEngine* xml = new TXMLEngine();
  XMLDocPointer_t xmldoc = xml->ParseFile(datacard.c_str());
  if (xmldoc==0) {
    std::cerr << "Exp >> " << "Can not parse input: " << datacard << std::endl;
    delete xml;
    return;
  }
  XMLNodePointer_t root_node = xml->DocGetRootElement(xmldoc);
  fGeometryFile          = util::XML2String(xml,root_node,"GeometryFile");
  fSimTargetVolume       = util::XML2String(xml,root_node,"SimTargetVolume");
  fMinEnergyCut          = util::XML2Dbl(xml,root_node,"ParticleThresholds/MinEnergyCut");
  fGammaCut              = util::XML2Dbl(xml,root_node,"ParticleThresholds/GammaCut");
  fElectronCut           = util::XML2Dbl(xml,root_node,"ParticleThresholds/ElectronCut");
  fPositronCut           = util::XML2Dbl(xml,root_node,"ParticleThresholds/PositronCut");
  fNeutronCut            = util::XML2Dbl(xml,root_node,"ParticleThresholds/NeutronCut");
  fRunVisMacro           = util::XML2Bool(xml,root_node,"RunVisMacro");
  fPhysicsList           = util::XML2String(xml,root_node,"PhysicsList");
  fEMPhysicsList         = util::XML2String(xml,root_node,"EMPhysicsList");
  fHadPhysicsList        = util::XML2String(xml,root_node,"HadPhysicsList");
  fMagneticFieldStrength = util::XML2Dbl(xml,root_node,"MagneticFieldStrength");
  fTrackingVerbose       = (int)util::XML2Dbl(xml,root_node,"TrackingVerbose");
  // Particle gun options
  fPositionX             = util::XML2Dbl(xml,root_node,"ParticleGun/PositionX");
  fPositionY             = util::XML2Dbl(xml,root_node,"ParticleGun/PositionY");
  fPositionZ             = util::XML2Dbl(xml,root_node,"ParticleGun/PositionZ");
  fMomentumX             = util::XML2Dbl(xml,root_node,"ParticleGun/MomentumX");
  fMomentumY             = util::XML2Dbl(xml,root_node,"ParticleGun/MomentumY");
  fMomentumZ             = util::XML2Dbl(xml,root_node,"ParticleGun/MomentumZ");
  fMinEnergy             = util::XML2Dbl(xml,root_node,"ParticleGun/MinEnergy");
  fMaxEnergy             = util::XML2Dbl(xml,root_node,"ParticleGun/MaxEnergy");
  fPDG                   = util::XML2Dbl(xml,root_node,"ParticleGun/PDG");
  fgauss                 = util::XML2Dbl(xml,root_node,"ParticleGun/Gauss");
}

<|endoftext|>


<commit_before>// ------------------------------------------------------------------
// pion-net: a C++ framework for building lightweight HTTP interfaces
// ------------------------------------------------------------------
// Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//

#ifndef __PION_HTTPREQUEST_HEADER__
#define __PION_HTTPREQUEST_HEADER__

#include <boost/shared_ptr.hpp>
#include <pion/PionConfig.hpp>
#include <pion/net/HTTPMessage.hpp>
#include <pion/net/PionUser.hpp>

namespace pion {	// begin namespace pion
namespace net {		// begin namespace net (Pion Network Library)

///
/// HTTPRequest: container for HTTP request information
///
class HTTPRequest
	: public HTTPMessage
{
public:

	/**
	 * constructs a new HTTPRequest object
	 *
	 * @param resource the HTTP resource to request
	 */
	HTTPRequest(const std::string& resource)
		: m_method(REQUEST_METHOD_GET), m_resource(resource) {}

	/// constructs a new HTTPRequest object (default constructor)
	HTTPRequest(void) : m_method(REQUEST_METHOD_GET) {}

	/// virtual destructor
	virtual ~HTTPRequest() {}

	/// clears all request data
	virtual void clear(void) {
		HTTPMessage::clear();
		m_method.erase();
		m_resource.erase();
		m_original_resource.erase();
		m_query_string.erase();
		m_query_params.clear();
		m_cookie_params.clear();
		m_user_record.reset();
		m_charset.clear();
	}

	/// the content length of the message can never be implied for requests
	virtual bool isContentLengthImplied(void) const { return false; }

	/// returns the request method (i.e. GET, POST, PUT)
	inline const std::string& getMethod(void) const { return m_method; }

	/// returns the resource uri-stem to be delivered (possibly the result of a redirect)
	inline const std::string& getResource(void) const { return m_resource; }

	/// returns the resource uri-stem originally requested
	inline const std::string& getOriginalResource(void) const { return m_original_resource; }

	/// returns the uri-query or query string requested
	inline const std::string& getQueryString(void) const { return m_query_string; }

	/// returns a value for the query key if any are defined; otherwise, an empty string
	inline const std::string& getQuery(const std::string& key) const {
		return getValue(m_query_params, key);
	}

	/// returns a value for the cookie if any are defined; otherwise, an empty string
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline const std::string& getCookie(const std::string& key) const {
		return getValue(m_cookie_params, key);
	}

	/// returns the query parameters
	inline QueryParams& getQueryParams(void) {
		return m_query_params;
	}

	/// returns the cookie parameters
	inline CookieParams& getCookieParams(void) {
		return m_cookie_params;
	}

	/// returns true if at least one value for the query key is defined
	inline bool hasQuery(const std::string& key) const {
		return(m_query_params.find(key) != m_query_params.end());
	}

	/// returns true if at least one value for the cookie is defined
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline bool hasCookie(const std::string& key) const {
		return(m_cookie_params.find(key) != m_cookie_params.end());
	}

	/// sets the HTTP request method (i.e. GET, POST, PUT)
	inline void setMethod(const std::string& str) {
		m_method = str;
		clearFirstLine();
	}

	/// sets the resource or uri-stem originally requested
	inline void setResource(const std::string& str) {
		m_resource = m_original_resource = str;
		clearFirstLine();
	}

	/// changes the resource or uri-stem to be delivered (called as the result of a redirect)
	inline void changeResource(const std::string& str) { m_resource = str; }

	/// sets the uri-query or query string requested
	inline void setQueryString(const std::string& str) {
		m_query_string = str;
		clearFirstLine();
	}

	/// adds a value for the query key
	inline void addQuery(const std::string& key, const std::string& value) {
		m_query_params.insert(std::make_pair(key, value));
	}

	/// changes the value of a query key
	inline void changeQuery(const std::string& key, const std::string& value) {
		changeValue(m_query_params, key, value);
	}

	/// removes all values for a query key
	inline void deleteQuery(const std::string& key) {
		deleteValue(m_query_params, key);
	}

	/// use the query parameters to build a query string for the request
	inline void useQueryParamsForQueryString(void) {
		setQueryString(make_query_string(m_query_params));
	}

	/// use the query parameters to build POST content for the request
	inline void useQueryParamsForPostContent(void) {
		std::string post_content(make_query_string(m_query_params));
		setContentLength(post_content.size());
		char *ptr = createContentBuffer();	// null-terminates buffer
		if (! post_content.empty())
			memcpy(ptr, post_content.c_str(), post_content.size());
		setMethod(REQUEST_METHOD_POST);
		setContentType(CONTENT_TYPE_URLENCODED);
	}

	/// adds a value for the cookie
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline void addCookie(const std::string& key, const std::string& value) {
		m_cookie_params.insert(std::make_pair(key, value));
	}

	/// changes the value of a cookie
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline void changeCookie(const std::string& key, const std::string& value) {
		changeValue(m_cookie_params, key, value);
	}

	/// removes all values for a cookie
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline void deleteCookie(const std::string& key) {
		deleteValue(m_cookie_params, key);
	}

	/// sets the user record for HTTP request after authentication
	inline void setUser(PionUserPtr user) { m_user_record = user; }

	/// get the user record for HTTP request after authentication
	inline PionUserPtr getUser() const { return m_user_record; }

protected:

	/// updates the string containing the first line for the HTTP message
	virtual void updateFirstLine(void) const {
		// start out with the request method
		m_first_line = m_method;
		m_first_line += ' ';
		// append the resource requested
		m_first_line += m_resource;
		if (! m_query_string.empty()) {
			// append query string if not empty
			m_first_line += '?';
			m_first_line += m_query_string;
		}
		m_first_line += ' ';
		// append HTTP version
		m_first_line += getVersionString();
	}

private:

	/// request method (GET, POST, PUT, etc.)
	std::string						m_method;

	/// name of the resource or uri-stem to be delivered
	std::string						m_resource;

	/// name of the resource or uri-stem originally requested
	std::string						m_original_resource;

	/// query string portion of the URI
	std::string						m_query_string;

	/// HTTP query parameters parsed from the request line and post content
	QueryParams						m_query_params;

	/// HTTP cookie parameters parsed from the "Cookie" request headers
	CookieParams					m_cookie_params;

	/// pointer to PionUser record if this request had been authenticated
	PionUserPtr						m_user_record;

	/// charset value from
	/// Content-Type: application/x-www-form-urlencoded; charset=<VALUE>
	std::string						m_charset;
};

/// data type for a HTTP request pointer
typedef boost::shared_ptr<HTTPRequest>		HTTPRequestPtr;

}	// end namespace net
}	// end namespace pion

#endif
<commit_msg>Added setContent() method for HTTPRequest to use with POST<commit_after>// ------------------------------------------------------------------
// pion-net: a C++ framework for building lightweight HTTP interfaces
// ------------------------------------------------------------------
// Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//

#ifndef __PION_HTTPREQUEST_HEADER__
#define __PION_HTTPREQUEST_HEADER__

#include <boost/shared_ptr.hpp>
#include <pion/PionConfig.hpp>
#include <pion/net/HTTPMessage.hpp>
#include <pion/net/PionUser.hpp>

namespace pion {	// begin namespace pion
namespace net {		// begin namespace net (Pion Network Library)

///
/// HTTPRequest: container for HTTP request information
///
class HTTPRequest
	: public HTTPMessage
{
public:

	/**
	 * constructs a new HTTPRequest object
	 *
	 * @param resource the HTTP resource to request
	 */
	HTTPRequest(const std::string& resource)
		: m_method(REQUEST_METHOD_GET), m_resource(resource) {}

	/// constructs a new HTTPRequest object (default constructor)
	HTTPRequest(void) : m_method(REQUEST_METHOD_GET) {}

	/// virtual destructor
	virtual ~HTTPRequest() {}

	/// clears all request data
	virtual void clear(void) {
		HTTPMessage::clear();
		m_method.erase();
		m_resource.erase();
		m_original_resource.erase();
		m_query_string.erase();
		m_query_params.clear();
		m_cookie_params.clear();
		m_user_record.reset();
		m_charset.clear();
	}

	/// the content length of the message can never be implied for requests
	virtual bool isContentLengthImplied(void) const { return false; }

	/// returns the request method (i.e. GET, POST, PUT)
	inline const std::string& getMethod(void) const { return m_method; }

	/// returns the resource uri-stem to be delivered (possibly the result of a redirect)
	inline const std::string& getResource(void) const { return m_resource; }

	/// returns the resource uri-stem originally requested
	inline const std::string& getOriginalResource(void) const { return m_original_resource; }

	/// returns the uri-query or query string requested
	inline const std::string& getQueryString(void) const { return m_query_string; }

	/// returns a value for the query key if any are defined; otherwise, an empty string
	inline const std::string& getQuery(const std::string& key) const {
		return getValue(m_query_params, key);
	}

	/// returns a value for the cookie if any are defined; otherwise, an empty string
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline const std::string& getCookie(const std::string& key) const {
		return getValue(m_cookie_params, key);
	}

	/// returns the query parameters
	inline QueryParams& getQueryParams(void) {
		return m_query_params;
	}

	/// returns the cookie parameters
	inline CookieParams& getCookieParams(void) {
		return m_cookie_params;
	}

	/// returns true if at least one value for the query key is defined
	inline bool hasQuery(const std::string& key) const {
		return(m_query_params.find(key) != m_query_params.end());
	}

	/// returns true if at least one value for the cookie is defined
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline bool hasCookie(const std::string& key) const {
		return(m_cookie_params.find(key) != m_cookie_params.end());
	}

	/// sets the HTTP request method (i.e. GET, POST, PUT)
	inline void setMethod(const std::string& str) {
		m_method = str;
		clearFirstLine();
	}

	/// sets the resource or uri-stem originally requested
	inline void setResource(const std::string& str) {
		m_resource = m_original_resource = str;
		clearFirstLine();
	}

	/// changes the resource or uri-stem to be delivered (called as the result of a redirect)
	inline void changeResource(const std::string& str) { m_resource = str; }

	/// sets the uri-query or query string requested
	inline void setQueryString(const std::string& str) {
		m_query_string = str;
		clearFirstLine();
	}

	/// adds a value for the query key
	inline void addQuery(const std::string& key, const std::string& value) {
		m_query_params.insert(std::make_pair(key, value));
	}

	/// changes the value of a query key
	inline void changeQuery(const std::string& key, const std::string& value) {
		changeValue(m_query_params, key, value);
	}

	/// removes all values for a query key
	inline void deleteQuery(const std::string& key) {
		deleteValue(m_query_params, key);
	}

	/// use the query parameters to build a query string for the request
	inline void useQueryParamsForQueryString(void) {
		setQueryString(make_query_string(m_query_params));
	}

	/// use the query parameters to build POST content for the request
	inline void useQueryParamsForPostContent(void) {
		std::string post_content(make_query_string(m_query_params));
		setContentLength(post_content.size());
		char *ptr = createContentBuffer();	// null-terminates buffer
		if (! post_content.empty())
			memcpy(ptr, post_content.c_str(), post_content.size());
		setMethod(REQUEST_METHOD_POST);
		setContentType(CONTENT_TYPE_URLENCODED);
	}

	/// add content (for POST) from string
	inline void setContent(const std::string &value) {
		setContentLength(value.size());
		char *ptr = createContentBuffer();
		if (! value.empty())
			memcpy(ptr, value.c_str(), value.size());
	}

	/// adds a value for the cookie
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline void addCookie(const std::string& key, const std::string& value) {
		m_cookie_params.insert(std::make_pair(key, value));
	}

	/// changes the value of a cookie
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline void changeCookie(const std::string& key, const std::string& value) {
		changeValue(m_cookie_params, key, value);
	}

	/// removes all values for a cookie
	/// since cookie names are insensitive, key should use lowercase alpha chars
	inline void deleteCookie(const std::string& key) {
		deleteValue(m_cookie_params, key);
	}

	/// sets the user record for HTTP request after authentication
	inline void setUser(PionUserPtr user) { m_user_record = user; }

	/// get the user record for HTTP request after authentication
	inline PionUserPtr getUser() const { return m_user_record; }

protected:

	/// updates the string containing the first line for the HTTP message
	virtual void updateFirstLine(void) const {
		// start out with the request method
		m_first_line = m_method;
		m_first_line += ' ';
		// append the resource requested
		m_first_line += m_resource;
		if (! m_query_string.empty()) {
			// append query string if not empty
			m_first_line += '?';
			m_first_line += m_query_string;
		}
		m_first_line += ' ';
		// append HTTP version
		m_first_line += getVersionString();
	}

private:

	/// request method (GET, POST, PUT, etc.)
	std::string						m_method;

	/// name of the resource or uri-stem to be delivered
	std::string						m_resource;

	/// name of the resource or uri-stem originally requested
	std::string						m_original_resource;

	/// query string portion of the URI
	std::string						m_query_string;

	/// HTTP query parameters parsed from the request line and post content
	QueryParams						m_query_params;

	/// HTTP cookie parameters parsed from the "Cookie" request headers
	CookieParams					m_cookie_params;

	/// pointer to PionUser record if this request had been authenticated
	PionUserPtr						m_user_record;

	/// charset value from
	/// Content-Type: application/x-www-form-urlencoded; charset=<VALUE>
	std::string						m_charset;
};

/// data type for a HTTP request pointer
typedef boost::shared_ptr<HTTPRequest>		HTTPRequestPtr;

}	// end namespace net
}	// end namespace pion

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: documentacceleratorconfiguration.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-01 19:34:47 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
#include <accelerators/documentacceleratorconfiguration.hxx>
#endif

//_______________________________________________
// own includes

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_ACCELERATORCONST_H_
#include <acceleratorconst.h>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_______________________________________________
// interface includes

//_______________________________________________
// other includes

#ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX
#include <comphelper/sequenceashashmap.hxx>
#endif

//_______________________________________________
// const

namespace framework
{

//-----------------------------------------------
// XInterface, XTypeProvider, XServiceInfo
DEFINE_XINTERFACE_2(DocumentAcceleratorConfiguration                   ,
                    AcceleratorConfiguration                           ,
                    DIRECT_INTERFACE(css::lang::XServiceInfo)          ,
                    DIRECT_INTERFACE(css::lang::XInitialization))
//                    DIRECT_INTERFACE(css::ui::XUIConfigurationStorage))

DEFINE_XTYPEPROVIDER_2_WITH_BASECLASS(DocumentAcceleratorConfiguration ,
                                      AcceleratorConfiguration         ,
                                      css::lang::XServiceInfo          ,
                                      css::lang::XInitialization)
//                                      css::ui::XUIConfigurationStorage)

DEFINE_XSERVICEINFO_MULTISERVICE(DocumentAcceleratorConfiguration                   ,
                                 ::cppu::OWeakObject                                ,
                                 SERVICENAME_DOCUMENTACCELERATORCONFIGURATION       ,
                                 IMPLEMENTATIONNAME_DOCUMENTACCELERATORCONFIGURATION)

DEFINE_INIT_SERVICE(DocumentAcceleratorConfiguration,
                    {
                        /*Attention
                        I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
                        to create a new instance of this class by our own supported service factory.
                        see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
                        */
                    }
                   )

//-----------------------------------------------
DocumentAcceleratorConfiguration::DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
    : AcceleratorConfiguration(xSMGR)
{
}

//-----------------------------------------------
DocumentAcceleratorConfiguration::~DocumentAcceleratorConfiguration()
{
    m_aPresetHandler.removeStorageListener(this);
}

//-----------------------------------------------
void SAL_CALL DocumentAcceleratorConfiguration::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
    throw(css::uno::Exception       ,
          css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    ::comphelper::SequenceAsHashMap lArgs(lArguments);
    m_xDocumentRoot = lArgs.getUnpackedValueOrDefault(
                        ::rtl::OUString::createFromAscii("DocumentRoot"),
                        css::uno::Reference< css::embed::XStorage >());

    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    impl_ts_fillCache();
}

//-----------------------------------------------
void SAL_CALL DocumentAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
    throw(css::uno::RuntimeException)
{
    // Attention! xStorage must be accepted too, if it's NULL !

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    sal_Bool bForgetOldStorages = m_xDocumentRoot.is();
    m_xDocumentRoot = xStorage;
    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    if (bForgetOldStorages)
        impl_ts_clearCache();

    if (xStorage.is())
        impl_ts_fillCache();
}

//-----------------------------------------------
sal_Bool SAL_CALL DocumentAcceleratorConfiguration::hasStorage()
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    return m_xDocumentRoot.is();
    // <- SAFE ----------------------------------
}

//-----------------------------------------------
void DocumentAcceleratorConfiguration::impl_ts_fillCache()
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::embed::XStorage > xDocumentRoot = m_xDocumentRoot;
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // Sometimes we must live without a document root.
    // E.g. if the document is readonly ...
    if (!xDocumentRoot.is())
        return;

    // get current office locale ... but dont cache it.
    // Otherwise we must be listener on the configuration layer
    // which seems to superflous for this small implementation .-)
    ::comphelper::Locale aLocale = impl_ts_getLocale();

    // May be the current document does not contain any
    // accelerator config? Handle it gracefully :-)
    try
    {
        // Note: The used preset class is threadsafe by itself ... and live if we live!
        // We do not need any mutex here.

        // open the folder, where the configuration exists
        m_aPresetHandler.connectToResource(
            PresetHandler::E_DOCUMENT,
            PresetHandler::RESOURCETYPE_ACCELERATOR(),
            ::rtl::OUString(),
            xDocumentRoot,
            aLocale);

        AcceleratorConfiguration::reload();
        m_aPresetHandler.addStorageListener(this);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        {}
}

//-----------------------------------------------
void DocumentAcceleratorConfiguration::impl_ts_clearCache()
{
    m_aPresetHandler.forgetCachedStorages();
}

} // namespace framework
<commit_msg>INTEGRATION: CWS ooo19126 (1.6.128); FILE MERGED 2005/09/05 13:05:56 rt 1.6.128.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: documentacceleratorconfiguration.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 01:03:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
#include <accelerators/documentacceleratorconfiguration.hxx>
#endif

//_______________________________________________
// own includes

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_ACCELERATORCONST_H_
#include <acceleratorconst.h>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_______________________________________________
// interface includes

//_______________________________________________
// other includes

#ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX
#include <comphelper/sequenceashashmap.hxx>
#endif

//_______________________________________________
// const

namespace framework
{

//-----------------------------------------------
// XInterface, XTypeProvider, XServiceInfo
DEFINE_XINTERFACE_2(DocumentAcceleratorConfiguration                   ,
                    AcceleratorConfiguration                           ,
                    DIRECT_INTERFACE(css::lang::XServiceInfo)          ,
                    DIRECT_INTERFACE(css::lang::XInitialization))
//                    DIRECT_INTERFACE(css::ui::XUIConfigurationStorage))

DEFINE_XTYPEPROVIDER_2_WITH_BASECLASS(DocumentAcceleratorConfiguration ,
                                      AcceleratorConfiguration         ,
                                      css::lang::XServiceInfo          ,
                                      css::lang::XInitialization)
//                                      css::ui::XUIConfigurationStorage)

DEFINE_XSERVICEINFO_MULTISERVICE(DocumentAcceleratorConfiguration                   ,
                                 ::cppu::OWeakObject                                ,
                                 SERVICENAME_DOCUMENTACCELERATORCONFIGURATION       ,
                                 IMPLEMENTATIONNAME_DOCUMENTACCELERATORCONFIGURATION)

DEFINE_INIT_SERVICE(DocumentAcceleratorConfiguration,
                    {
                        /*Attention
                        I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
                        to create a new instance of this class by our own supported service factory.
                        see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
                        */
                    }
                   )

//-----------------------------------------------
DocumentAcceleratorConfiguration::DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
    : AcceleratorConfiguration(xSMGR)
{
}

//-----------------------------------------------
DocumentAcceleratorConfiguration::~DocumentAcceleratorConfiguration()
{
    m_aPresetHandler.removeStorageListener(this);
}

//-----------------------------------------------
void SAL_CALL DocumentAcceleratorConfiguration::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
    throw(css::uno::Exception       ,
          css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    ::comphelper::SequenceAsHashMap lArgs(lArguments);
    m_xDocumentRoot = lArgs.getUnpackedValueOrDefault(
                        ::rtl::OUString::createFromAscii("DocumentRoot"),
                        css::uno::Reference< css::embed::XStorage >());

    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    impl_ts_fillCache();
}

//-----------------------------------------------
void SAL_CALL DocumentAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
    throw(css::uno::RuntimeException)
{
    // Attention! xStorage must be accepted too, if it's NULL !

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    sal_Bool bForgetOldStorages = m_xDocumentRoot.is();
    m_xDocumentRoot = xStorage;
    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    if (bForgetOldStorages)
        impl_ts_clearCache();

    if (xStorage.is())
        impl_ts_fillCache();
}

//-----------------------------------------------
sal_Bool SAL_CALL DocumentAcceleratorConfiguration::hasStorage()
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    return m_xDocumentRoot.is();
    // <- SAFE ----------------------------------
}

//-----------------------------------------------
void DocumentAcceleratorConfiguration::impl_ts_fillCache()
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::embed::XStorage > xDocumentRoot = m_xDocumentRoot;
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // Sometimes we must live without a document root.
    // E.g. if the document is readonly ...
    if (!xDocumentRoot.is())
        return;

    // get current office locale ... but dont cache it.
    // Otherwise we must be listener on the configuration layer
    // which seems to superflous for this small implementation .-)
    ::comphelper::Locale aLocale = impl_ts_getLocale();

    // May be the current document does not contain any
    // accelerator config? Handle it gracefully :-)
    try
    {
        // Note: The used preset class is threadsafe by itself ... and live if we live!
        // We do not need any mutex here.

        // open the folder, where the configuration exists
        m_aPresetHandler.connectToResource(
            PresetHandler::E_DOCUMENT,
            PresetHandler::RESOURCETYPE_ACCELERATOR(),
            ::rtl::OUString(),
            xDocumentRoot,
            aLocale);

        AcceleratorConfiguration::reload();
        m_aPresetHandler.addStorageListener(this);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        {}
}

//-----------------------------------------------
void DocumentAcceleratorConfiguration::impl_ts_clearCache()
{
    m_aPresetHandler.forgetCachedStorages();
}

} // namespace framework
<|endoftext|>