diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1998-06-18 04:07:34 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1998-06-18 04:07:34 +0000 |
commit | dfdc610629ae7e8fd4839082737dbaad95da9847 (patch) | |
tree | bb5bb9690ce49b7c8292dd6ded567bff40d73a2d /ace/CLASSIX | |
parent | 8f712b526c16318191816fe5155ede4330836f8b (diff) | |
download | ATCD-dfdc610629ae7e8fd4839082737dbaad95da9847.tar.gz |
*** empty log message ***
Diffstat (limited to 'ace/CLASSIX')
43 files changed, 4660 insertions, 0 deletions
diff --git a/ace/CLASSIX/Acceptor.cpp b/ace/CLASSIX/Acceptor.cpp new file mode 100644 index 00000000000..bf32906ea4c --- /dev/null +++ b/ace/CLASSIX/Acceptor.cpp @@ -0,0 +1,199 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "CLASSIX/Acceptor.h" + +#if defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "CLASSIX/Acceptor.i" +#endif /* ACE_LACKS_INLINE_FUNCTIONS */ + +#include "ace/Synch.h" + +ACE_ALLOC_HOOK_DEFINE (ACE_CLASSIX_Acceptor) + +// General purpose routine for performing server creation. + +ACE_CLASSIX_Acceptor::ACE_CLASSIX_Acceptor (const ACE_Addr &local_sap, + int reuse_addr, + int protocol_family, + int backlog, + int protocol, + ACE_Reactor* theReactor) + : port_ (0), + reactor_ (theReactor) +{ + ACE_TRACE ("ACE_CLASSIX_Acceptor::ACE_CLASSIX_Acceptor"); + if (this->open (local_sap, reuse_addr, protocol_family, + backlog, protocol, theReactor) == -1) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT ("%p\n"), + ASYS_TEXT ("ACE_CLASSIX_Acceptor"))); +} + +// General purpose routine for performing server creation. + +int +ACE_CLASSIX_Acceptor::open (const ACE_Addr & theLocalSap, + int /* reuse_addr */, + int theProtocolFamily, + int /* backlog */, + int /* protocol */, + ACE_Reactor* theReactor) +{ + // make sure that the client requests for a "CLASSIX" family. + + if (theProtocolFamily != ACE_CLASSIX_Addr::AF_CLASSIX) + return -1; + + // Setup local address + + int error = 0; + if (theLocalSap == ACE_Addr::sap_any) + { + this->port_ = new ACE_CLASSIX_Port_Core (); + ACE_ASSERT (this->port_); + error = this->addr_.set (*this->port_); + } + else + error = this->addr_.set (theLocalSap); + + if (error != 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_CLASSIX_Acceptor::open ()::" + "Cannot setup address\n"), -1); + + // Make the port "selectable" + + if (this->addr_.selectable () != 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_CLASSIX_Acceptor::open ()::" + "Cannot enable port\n"), -1); + + this->reactor_ = theReactor; + return 0; +} + +// General purpose routine for accepting new connections. + +int +ACE_CLASSIX_Acceptor::accept (ACE_CLASSIX_Stream &new_stream, + ACE_Addr *remote_addr, + ACE_Time_Value* /* timeout */, + int /* restart */, + int /* reset_new_handle */) const +{ + ACE_TRACE ("ACE_CLASSIX_Acceptor::accept"); + + // Get peer's address info + + size_t size = 0; + if (this->reactor_->get_current_info (this->get_handle (), size) + == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_CLASSIX_Acceptor:.accept ()::" + "Cannot get peer addr\n"), -1); + + ACE_CLASSIX_Acceptor::Peer_Union data; + ACE_CLASSIX_Msg rmsg (&data, sizeof (ACE_CLASSIX_Acceptor::Peer_Union)); + if (size != sizeof (ACE_CLASSIX_Acceptor::Peer_Union) + || ::ipcGetData (rmsg.get ()) != size) + ACE_ERROR_RETURN ((LM_ERROR, "%t" + "ACE_CLASSIX_Acceptor::accept::ipcGetData (%d)\n", + size), + -1); + + // Set up Peer SAP + + int error = 0; + switch (data.type) + { + case ACE_CLASSIX_Addr::PORT: + error = new_stream.set_peer_sap (data.choose.port.peer); + break; + + case ACE_CLASSIX_Addr::GROUP: + error = new_stream.set_peer_sap (data.choose.group.peer); + break; + + case ACE_CLASSIX_Addr::STAMP: + error = new_stream.set_peer_sap (data.choose.stamp.peer); + break; + + case ACE_CLASSIX_Addr::DYNAMIC: + error = new_stream.set_peer_sap (data.choose.group.peer); + break; + + default: + ACE_ERROR_RETURN ((LM_ERROR, "ACE_CLASSIX_Accept::accept ()::" + "Invalid peer address\n"), -1); + } + + if (error != 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_CLASSIX_Accept::accept ()::" + "cannot set peer address\n"), -1); + + // Set up local SAP & tell the peer + + data.type = ACE_CLASSIX_Addr::UNDEFINED; + + if (remote_addr != 0) + { + if (remote_addr->get_type () == ACE_CLASSIX_Addr::AF_CLASSIX && + ((ACE_CLASSIX_Addr*) remote_addr)->is_type == + ACE_CLASSIX_Addr::PORT) + { + new_stream.get_local_sap ().set (*remote_addr); + data.type = ACE_CLASSIX_Addr::PORT; + } + } + else + { + ACE_CLASSIX_Port_Core *port = new ACE_CLASSIX_Port_Core (); + if (new_stream.set_local_port (port) == 0) + data.type = ACE_CLASSIX_Addr::PORT;; + } + + data.choose.port.peer = + new_stream.get_local_sap ().get_addr ().get_id (); + + ACE_CLASSIX_Msg smsg (&data, sizeof (ACE_CLASSIX_Acceptor::Peer_Union)); + + if (::ipcReply (smsg.get ()) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_CLASSIX_Accept::accept ()::" + "cannot deliver server address to peer\n"), -1); + + // Make new_stream's local SAP selectable. + if (new_stream.selectable () != 0) + return -1; + + return 0; +} + +int +ACE_CLASSIX_Acceptor::close (void) +{ + ACE_TRACE ("ACE_CLASSIX_ACceptor::close"); + int result = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + delete this->port_; + this->port_ = 0; + ((ACE_CLASSIX_Port) this->addr_.get_addr ()).clear (); + } + return 0; +} + + +int +ACE_CLASSIX_Acceptor::get_local_addr (ACE_Addr &theAddr) const +{ + int size = theAddr.get_size (); + if (size < this->addr_.get_addr ().get_size ()) + return -1; + + return this->addr_.get_addr (theAddr); +} + +void +ACE_CLASSIX_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_CLASSIX_Acceptor::dump"); +} diff --git a/ace/CLASSIX/Acceptor.h b/ace/CLASSIX/Acceptor.h new file mode 100644 index 00000000000..00838fbd00a --- /dev/null +++ b/ace/CLASSIX/Acceptor.h @@ -0,0 +1,141 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// CLASSIX/Acceptor.h +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#if !defined (ACE_CLASSIX_ACCEPTOR_H) +#define ACE_CLASSIX_ACCEPTOR_H + +#include "CLASSIX/Stream.h" +#include "ace/Time_Value.h" + +class ACE_Export ACE_CLASSIX_Acceptor +{ + // = TITLE + // Defines the format and interface for a connection + // oriented <ACE_CLASSIX_Stream> acceptor. + // + // = DESCRIPTION + // This class is the counter part of the <ACE_CLASSIX_Connector> + // class. It exchanges SAP information to set up a logical + // connection. + // + // Data format passed between a connector and this class uses + // Peer_Union structure. + // + // = SEE ALSO + // ACE_CLASSIX_Connector + // +public: + struct Peer_Port + { + KnUniqueId peer; + }; + + struct Peer_Group + { + KnCap peer; + }; + + struct Peer_Stamp + { + int peer; + }; + + struct Peer_Union + { + int type; + union + { + Peer_Port port; + Peer_Group group; + Peer_Stamp stamp; + }choose; + }; + + // = Initialization methods. + ACE_CLASSIX_Acceptor (ACE_Reactor* = ACE_Reactor::instance()); + // Default constructor. + + ACE_CLASSIX_Acceptor (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = ACE_CLASSIX_Addr::AF_CLASSIX, + int backlog = 0, + int protocol = 0, + ACE_Reactor* = ACE_Reactor::instance()); + // Initiate a passive mode socket. + + virtual ~ACE_CLASSIX_Acceptor (void); + // Default dtor. + + int open (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = ACE_CLASSIX_Addr::AF_CLASSIX, + int backlog = 5, + int protocol = 0, + ACE_Reactor* = ACE_Reactor::instance()); + // Initiate a passive mode socket. + int close (void); + // Closes down the listening port. + + // = Passive connection acceptance method. + int accept (ACE_CLASSIX_Stream &new_stream, + ACE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1, + int reset_new_handle = 0) const; + // Accept a new data transfer connection. A <timeout> of 0 means + // block forever, a <timeout> of {0, 0} means poll. <restart> == 1 + // means "restart if interrupted." + + // = ACCESS + ACE_HANDLE get_handle (void) const; + // Get the underlying descriptor. + int get_local_addr (ACE_Addr &) const; + // Return the local endpoint address in the referenced ACE_Addr. + // Returns 0 if successful, else -1. + + void reactor(ACE_Reactor*); + // reset the reactor + + // = META-TYPE info + typedef ACE_CLASSIX_Addr PEER_ADDR; + typedef ACE_CLASSIX_Stream PEER_STREAM; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + +private: + // int get_remote_addr (ACE_Addr &) const; + // Do not allow this function to percolate up to this interface... + + ACE_CLASSIX_Port_Core *port_; + // optional port. + // If 0, default port is used. + ACE_CLASSIX_SAP addr_; + + ACE_Reactor *reactor_; + // for reference only. Does not own it +}; + +#if !defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "CLASSIX/Acceptor.i" +#endif /* ACE_LACKS_INLINE_FUNCTIONS */ + +#endif /* ACE_CLASSIX_ACCEPTOR_H */ diff --git a/ace/CLASSIX/Acceptor.i b/ace/CLASSIX/Acceptor.i new file mode 100644 index 00000000000..c8dc9384ada --- /dev/null +++ b/ace/CLASSIX/Acceptor.i @@ -0,0 +1,31 @@ +/* -*- C++ -*- */ +// $Id$ + +// Do nothing routine for constructor. +ACE_INLINE +ACE_CLASSIX_Acceptor::ACE_CLASSIX_Acceptor (ACE_Reactor* theReactor) + : port_ (0), + reactor_ (theReactor) +{ + ACE_TRACE ("ACE_CLASSIX_Acceptor::ACE_CLASSIX_Acceptor"); +} + +ACE_INLINE +ACE_CLASSIX_Acceptor::~ACE_CLASSIX_Acceptor(void) +{ + delete this->port_; +} + +ACE_INLINE +void +ACE_CLASSIX_Acceptor::reactor(ACE_Reactor* theReactor) +{ + this->reactor_ = theReactor; +} + +ACE_INLINE +ACE_HANDLE +ACE_CLASSIX_Acceptor::get_handle(void) const +{ + return this->addr_.get_handle(); +} diff --git a/ace/CLASSIX/Addr.cpp b/ace/CLASSIX/Addr.cpp new file mode 100644 index 00000000000..f9872466453 --- /dev/null +++ b/ace/CLASSIX/Addr.cpp @@ -0,0 +1,13 @@ +/* -*- C++ -*- */ +// $Id$ + +// Defines the ClassiX IPC address family address format. + +#define ACE_BUILD_DLL +#include "CLASSIX/Addr.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_Addr) diff --git a/ace/CLASSIX/Addr.h b/ace/CLASSIX/Addr.h new file mode 100644 index 00000000000..77664defc35 --- /dev/null +++ b/ace/CLASSIX/Addr.h @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ipp_ace +// +// = FILENAME +// CLASSIX_Addr.h +// +// = AUTHOR +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#if !defined (ACE_CLASSIX_ADDR_H) +#define ACE_CLASSIX_ADDR_H + +#include "ace/ACE.h" +#include "ace/Addr.h" + +#include <ipc/chIpc.h> +#include <CLASSIX/OS.h> + +class ACE_Export ACE_CLASSIX_Addr : public ACE_Addr +{ + // = TITLE + // Defines the ClassiX IPC address format. + // + // = DESCRIPTION + // This class defines basic interfaces for "ACE-like" address for + // Chorus port. +public: + enum + { + ACE_CLASSIX_ADDR_UNKNOWN = ACE_INVALID_HANDLE, /* K_NONEPORT */ + ACE_CLASSIX_ADDR_DEFAULT = K_DEFAULTPORT, + AF_CLASSIX = AF_MAX + 1 + }; + + enum Addr_Type + { + PORT, // use Peer_Port + GROUP, // use Peer_Group + STAMP, // use peer_Stamp + DYNAMIC, // use Peer_Group + UNDEFINED + }; + + + /* -----------------------------------------------------*/ + // = INITIALIZATION + ACE_CLASSIX_Addr(int /* size of the underlying address structure*/); + virtual ~ACE_CLASSIX_Addr (void); + + + /* -----------------------------------------------------*/ + // = Direct initialization methods (useful after the object has been + // constructed). + // Returns 0 on success, -1 otherwise. + // + + /* -----------------------------------------------------*/ + // = ACCESS + // + virtual const KnUniqueId& get_id (void) const; + // Returns a reference to the unique identifier + + virtual ACE_HANDLE get_port_number(void) const; + virtual ACE_HANDLE get_handle(void) const; + // Returns the local port no( can be used as an ACE_HANDLE) + + virtual int is_configured(void) const; + // Returns 1, if address information is proper; Returns 0 otherwise + virtual ACE_CLASSIX_Addr::Addr_Type is_type(void) const; + // returns the type of the address + + // = HELPER + virtual void dump(void) const; + + ACE_ALLOC_HOOK_DECLARE; + // Declares the dynamic allocation hooks. + +private: +}; + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_CLASSIX_ADDR_H */ diff --git a/ace/CLASSIX/Addr.i b/ace/CLASSIX/Addr.i new file mode 100644 index 00000000000..13cc5fd48e3 --- /dev/null +++ b/ace/CLASSIX/Addr.i @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +// $Id$ + +// CLASSIX_Addr.i + +ACE_INLINE +ACE_CLASSIX_Addr::ACE_CLASSIX_Addr(int theSize) + : ACE_Addr (AF_CLASSIX, theSize) +{ +} + +ACE_INLINE +ACE_CLASSIX_Addr::~ACE_CLASSIX_Addr(void) +{ +} + +ACE_INLINE +const KnUniqueId& +ACE_CLASSIX_Addr::get_id(void) const +{ + return ACE_CLASSIX_OS::null_KnUniqueId(); +} + +ACE_INLINE +ACE_HANDLE +ACE_CLASSIX_Addr::get_handle(void) const +{ + return ACE_INVALID_HANDLE; +} + +ACE_INLINE +ACE_HANDLE +ACE_CLASSIX_Addr::get_port_number(void) const +{ + return get_handle(); +} + +ACE_INLINE +int +ACE_CLASSIX_Addr::is_configured(void) const +{ + return 0; +} + +ACE_INLINE +ACE_CLASSIX_Addr::Addr_Type +ACE_CLASSIX_Addr::is_type(void) const +{ + return ACE_CLASSIX_Addr::UNDEFINED; +} + +ACE_INLINE +void +ACE_CLASSIX_Addr::dump(void) const +{ +} diff --git a/ace/CLASSIX/Connector.cpp b/ace/CLASSIX/Connector.cpp new file mode 100644 index 00000000000..5ad52369fa9 --- /dev/null +++ b/ace/CLASSIX/Connector.cpp @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// CLASSIX/CLD_Connector.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#define ACE_BUILD_DLL +#include "CLASSIX/CLD_Connector.h" +#include "CLASSIX/Addr.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_CLD_Connector) + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/CLD_Connector.i" +#endif /* __ACE_INLINE__ */ + +// Set up remote port information + +int +ACE_CLASSIX_CLD_Connector::connect (ACE_CLASSIX_Stream &new_stream, + const ACE_Addr & theRemote,/* remote_sap */ + ACE_Time_Value *, /* timeout */ + const ACE_Addr & theLocal, + int, /* reuse_addr */ + int theFlag, /* flags */ + int, /* perms */ + int theProtocolFamily, + int /* protocol */) + +{ + ACE_TRACE ("ACE_CLASSIX_CLD_Connector::connect"); + + // Set up peer SAP + if (theRemote == ACE_Addr::sap_any || + new_stream.set_peer_sap(theRemote) != 0) + ACE_ERROR_RETURN((LM_ERROR, "ACE_CLASSIX_CLD_Connector::connect()::" + "Invalid Connector SAP\n"), -1); + + // Set up local SAP + + if (theLocal == ACE_Addr::sap_any) + { + // if local sap has not been configured + // create a port and use it as the local SAP + new_stream.open(); + } + else + { + // replace the local SAP information + new_stream.close(); + new_stream.open(theLocal); + } + + // Make the local SAP "selectable", if requested via the flag + + if (new_stream.local_sap().is_configured() && + new_stream.peer_sap().is_configured() && /* remote sap info exist */ + theProtocolFamily == ACE_CLASSIX_Addr::AF_CLASSIX) + { + new_stream.control(); + // setup the default delivery mode, if applicable + if (theFlag & ACE_CLASSIX_CLD_Connector::ENABLE) + { + if (new_stream.selectable() == 0) + return 0; + else + return -1; + } + return 0; + } + else + return -1; +} + +void +ACE_CLASSIX_CLD_Connector::dump (void) const +{ + ACE_TRACE ("ACE_CLASSIX_CLD_Connector::dump"); +} diff --git a/ace/CLASSIX/Connector.h b/ace/CLASSIX/Connector.h new file mode 100644 index 00000000000..c7fedc39598 --- /dev/null +++ b/ace/CLASSIX/Connector.h @@ -0,0 +1,127 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// CLASSIX/CLD_Connector.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_CLASSIX_CLD_CONNECTOR_H +#define ACE_CLASSIX_CLD_CONNECTOR_H + +#include "CLASSIX/Stream.h" + +class ACE_CLASSIX_CLD_Connector +{ + // = TITLE + // Defines an CLASSIX IPC connectionless connection factory for the + // template methods in <ACE_Connector>. + // + // = DESCRIPTION + // This is used when a client needs to communicate with a server + // whose SAP address is known beforehand. + // + // Although there is a connection + // procedure, no connection is actually taken place + // between the client and server, since Chorus IPC does not have + // connection semantics. + // The connect procedure is necessary for + // compatibility with <ACE_SOCK_Connector> class. + // + // This class will simplify the client's + // program, since it provides connection-like communication + // mechanism. + // + // = NOTES + // The server in this case trusts everyone who lands on the + // server's SAP. + // + // = SEE ALSO + // ACE_CLASSIX_COD_Connector +public: + // = Connect options + enum OPTIONS + { + // Do not enable the local SAP + // (so that the Reactor will not monitor the port) + ENABLE = 0x1 + }; + + // = Initialization routines. + ACE_CLASSIX_CLD_Connector (void); + // Default constructor. + + ACE_CLASSIX_CLD_Connector (ACE_CLASSIX_Stream &new_stream, + const ACE_Addr &remote_sap + = ACE_Addr::sap_any, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol_family + = ACE_CLASSIX_Addr::AF_CLASSIX, + int protocol = 0); + // Emulates connection semantics so that it can be plugged into + // <ACE_Connector> + // Actively connect local SAP and remote SAP togeter. + // Produce a <new_stream> if things go well. + // + // <remote_sap> is the peer's address. In ACE_SOCK_Connector it refers to + // the acceptor's address. In connectionless mode, we do not have + // an acceptor. The <remote_sap> address will be copied to the new stream + // if things goes well. + // + // If <local_sap> refers to any address, a port will be + // allocated and will be used as a local SAP. + // + // The rest parameters are there so that this class can be plugged into + // <ACE_Connector>. + + virtual int connect (ACE_CLASSIX_Stream &new_stream, + const ACE_Addr &remote_sap = ACE_Addr::sap_any, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol_family = ACE_CLASSIX_Addr::AF_CLASSIX, + int protocol = 0); + + // Factory method used in <ACE_Connector>::connect_svc_handler() + + // Initialization method when default constructor is used. + // See the comments for the corresponding constructor + + virtual int reset_new_handle (ACE_HANDLE handle); + // Factory method used in ACE_Connector::handle_output(). + // Meant for resetting any event associations on this handle + // Does nothig. + + // = HELPER + void dump(void) const; + +private: + + ACE_CLASSIX_CLD_Connector(ACE_CLASSIX_CLD_Connector const&); + ACE_CLASSIX_CLD_Connector const& operator=(ACE_CLASSIX_CLD_Connector const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/CLD_Connector.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_CLASSIX_CLD_CONNECTOR_H */ diff --git a/ace/CLASSIX/Connector.i b/ace/CLASSIX/Connector.i new file mode 100644 index 00000000000..66cac167cab --- /dev/null +++ b/ace/CLASSIX/Connector.i @@ -0,0 +1,37 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_CLD_Connector::ACE_CLASSIX_CLD_Connector (ACE_CLASSIX_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_CLASSIX_CLD_Connector::ACE_CLASSIX_CLD_Connector"); + if (this->connect (new_stream, remote_sap, timeout, local_sap, + reuse_addr, flags, perms, + protocol_family, protocol) == -1) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT ("%p\n"), ASYS_TEXT + ("ACE_CLASSIX_CLD_Connector::ACE_CLASSIX_CLD_Connector"))); +} + +// Do-nothing constructor... + +ACE_INLINE +ACE_CLASSIX_CLD_Connector::ACE_CLASSIX_CLD_Connector (void) +{ + ACE_TRACE ("ACE_CLASSIX_CLD_Connector::ACE_CLASSIX_CLD_Connector"); +} + +ACE_INLINE +int +ACE_CLASSIX_CLD_Connector::reset_new_handle (ACE_HANDLE /* handle */) +{ + return 0; +} diff --git a/ace/CLASSIX/Dgram_Mcast.cpp b/ace/CLASSIX/Dgram_Mcast.cpp new file mode 100644 index 00000000000..6d2049f2069 --- /dev/null +++ b/ace/CLASSIX/Dgram_Mcast.cpp @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// IPP +// +// = FILENAME +// CLASSIX/Dgram_Mcast.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Dgram_Mcast.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Dgram_Mcast.i" +#endif /* __ACE_INLINE__ */ +/* ------------------------------------------------------------------------- */ +ACE_CLASSIX_Dgram_Mcast::ACE_CLASSIX_Dgram_Mcast(void) + : ACE_CLASSIX_Stream() +{ +} + +ACE_CLASSIX_Dgram_Mcast::ACE_CLASSIX_Dgram_Mcast (int theStamp, + const ACE_CLASSIX_Port& thePort) + : ACE_CLASSIX_Stream() +{ + this->set_saps(theStamp, thePort); +} + +int +ACE_CLASSIX_Dgram_Mcast::set_saps(int theStamp, + const ACE_CLASSIX_Port& thePort) +{ + this->local_sap_.set_addr(thePort); + if (this->peer_sap_.set(theStamp) != 0) + { + errno = EADDRNOTAVAIL; + ACE_ERROR_RETURN((LM_ERROR, "ACE_CLASSIX_Dgram_Mcast- " + "failed to set up peer sap address \n"), -1); + } + else + { + this->dest_.target = this->peer_sap_.get_addr()->get_id(); + return 0; + } +} + + +int +ACE_CLASSIX_Dgram_Mcast::set_mode_(u_int theMode, int theSite) +{ + int result = K_EFAULT; + if (theMode <= K_FUNCXMODE && + (result =::uiSite(&this->dest_.coTarget, theSite)) == 0) + result = ::ipcTarget(&this->dest_.target, theMode); + + if (result != 0) + { + errno = ACE_CLASSIX_OS::convert_io_error(result); + result = -1; + } + return result; +} + +int +ACE_CLASSIX_Dgram_Mcast::set_mode_(u_int theMode) +{ + int result = K_EFAULT; + if (theMode <= K_FUNCXMODE ) + result = ::ipcTarget(&this->dest_.target, theMode); + + if (result < 0) + { + errno = ACE_CLASSIX_OS::convert_io_error(result); + result = -1; + } + return result; +} + + +void +ACE_CLASSIX_Dgram_Mcast::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, "ACE_CLASSIX_Dgram_Mcast...\n")); + this->ACE_CLASSIX_Stream::dump(); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/Dgram_Mcast.h b/ace/CLASSIX/Dgram_Mcast.h new file mode 100644 index 00000000000..bf40182c1b3 --- /dev/null +++ b/ace/CLASSIX/Dgram_Mcast.h @@ -0,0 +1,90 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// IPP +// +// = FILENAME +// CLASSIX/Dgram_Mcast.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef IPP_WRAPPER_CLASSIX_DGRAM_MCAST_H +#define IPP_WRAPPER_CLASSIX_DGRAM_MCAST_H + +/* ------------------------------------------------------------------------- */ +#include <CLASSIX/Stream.h> + +class ACE_CLASSIX_Dgram_Mcast : public ACE_CLASSIX_Stream + // = TITLE + // Provides Dgram_Mcast interfaces for CLASSIX IPC communications. + // + // = DESCRIPTION + // This class represents multiple end-points for message delivery. + // All the remote ports are belong to the same group identified by + // a stamp. + // It uses the broadcast mode provided by ipcSend() to deliver + // messages. + // + // This class is most likely used in the server. + // +{ + public: + // = INITIALIZATION + ACE_CLASSIX_Dgram_Mcast(void); + // Default constructor, does not setup anything + + ACE_CLASSIX_Dgram_Mcast(int /* stamp */, + const ACE_CLASSIX_Port& = + *ACE_CLASSIX_DEFAULT_PORT::instance()); + // remote SAP = port group, local SAP = default port + + int set_saps(int /* stamp */, + const ACE_CLASSIX_Port& = + *ACE_CLASSIX_DEFAULT_PORT::instance()); + // remote SAP = port group, local SAP = default port + + //virtual ssize_t send (const void *, /* buf */ + // size_t /* n */) const; + + + // = HELPER + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + protected: + + virtual int set_mode_(u_int = K_BROADMODE); /* theMode */ + // Sets the addressing mode with the current setting of coTarget + virtual int set_mode_(u_int, /* mode */ int /* site */); + // Sets the addressing mode as well as the coTarget + + // Site information for delivery mode, see <ACE_CLASSIX_Stream::dest_ > + // Can be changed by control()/set_mode_() + int dest_site_; + + + private: + // Disable copy constructor + ACE_CLASSIX_Dgram_Mcast(ACE_CLASSIX_Dgram_Mcast const&); + ACE_CLASSIX_Dgram_Mcast const& operator=(ACE_CLASSIX_Dgram_Mcast const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Dgram_Mcast.i" +#endif /* __ACE_INLINE__ */ + +#endif /* IPP_WRAPPER_CLASSIX_DGRAM_MCAST_H */ diff --git a/ace/CLASSIX/Group.cpp b/ace/CLASSIX/Group.cpp new file mode 100644 index 00000000000..5df4d934221 --- /dev/null +++ b/ace/CLASSIX/Group.cpp @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Group.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Group.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Group.i" +#endif /* __ACE_INLINE__ */ +/* ------------------------------------------------------------------------- */ + +void +ACE_CLASSIX_Group::init_(void) +{ + this->clear_config_(); + this->addr_.group_.ui.uiHead = this->addr_.group_.ui.uiTail = 0; + this->addr_.group_.key.keyHead = this->addr_.group_.key.keyTail = 0; +} + +void +ACE_CLASSIX_Group::set_addr(void* theSrc, int theLen) +{ + if (theLen > this->get_size()) + return; + + ACE_OS::memcpy ((void *) &this->addr_, + (void *) theSrc, theLen); +} + +void +ACE_CLASSIX_Group::set_addr(const KnCap& thePeer) +{ + this->addr_.group_ = thePeer; + this->set_config_(); +} + + +int +ACE_CLASSIX_Group::insert(const ACE_CLASSIX_Port* thePort) +{ + if (this->is_configured()) + return ::grpPortInsert((KnCap*) &this->get_cap(), + (KnUniqueId*) &thePort->get_id()); + else + return K_EINVAL; +} + +int +ACE_CLASSIX_Group::remove(const ACE_CLASSIX_Port* thePort) +{ + if (this->is_configured()) + return ::grpPortRemove((KnCap*) &this->get_cap(), + (KnUniqueId*) &thePort->get_id()); + else + return K_EINVAL; +} + +void +ACE_CLASSIX_Group::dump(void) const +{ + ACE_DEBUG ((LM_DEBUG, "ACE_CLASSIX_Group...\n")); + char s[200]; + if (!this->is_configured()) + ACE_OS::sprintf(s, "Group has not been setup\n"); + else + { + const KnCap &group = this->get_cap(); + ACE_OS::sprintf (s, "id head = %d(%x), id tail = %d(%x)\n" + "key head = %d(%x) key tail = %d(%x)\n", + group.ui.uiHead, group.ui.uiHead, + group.ui.uiTail, group.ui.uiTail, + group.key.keyHead, group.key.keyHead, + group.key.keyTail, group.key.keyTail); + } + ACE_DEBUG ((LM_DEBUG, "\n%s", s)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/Group.h b/ace/CLASSIX/Group.h new file mode 100644 index 00000000000..1e56e868841 --- /dev/null +++ b/ace/CLASSIX/Group.h @@ -0,0 +1,114 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Group.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_WRAPPER_CLASSIX_GROUP_H +#define ACE_WRAPPER_CLASSIX_GROUP_H + +/* ------------------------------------------------------------------------- */ +#include "CLASSIX/Addr.h" +#include "CLASSIX/Port.h" + +class ACE_CLASSIX_Group : public ACE_CLASSIX_Addr + // = TITLE + // Wrapper over Chorus's Group concept. + // + // = DESCRIPTION + // Provides interface to insert and remove ports in the group which is + // created based on a given KnCap. This"<KnCap> is the unique + // identifier of the group. + // + // = NOTE + // Chorus does not provide facility to remove a group from the system, + // nor explicitly create a group. + // As such, the wrapper allows users to freely change from one group + // to the other within the same <ACE_CLASSIX_Group> instance. + // + // = SEE ALSO + // <ACE_CLASSIX_Group_Stamp>, <ACE_CLASSIX_Group_Dynamic> + // +{ + public: + // = INITIALIZATION + ACE_CLASSIX_Group(void*, /* group id */ int /* len */); + // Sets up the group wrapper using the supplied group id. + ACE_CLASSIX_Group(const KnCap&); + // Sets up the group wrapper using the supplied KnCap + + // = ACCESS + int is_configured(void) const; + // Returns 1, if it contains valid group id; 0, otherwise. + virtual ACE_CLASSIX_Addr::Addr_Type is_type(void) const; + // returns GROUP type + void* get_addr(void) const; + // Returns the group id + virtual const KnUniqueId& get_id (void) const; + // Returns a reference to the unique identifier + virtual void set_addr(void* /* source */, int /* len */); + // Sets the group information according to the supplied data + // in raw format. + virtual void set_addr(const KnCap&); + // Sets the group information according to the supplied KnCap. + const KnCap& get_cap(void) const; + // Returns the capability to the supplied location + // If the address is not configured, the return value is unpredictable. + int insert(const ACE_CLASSIX_Port*); + int remove (const ACE_CLASSIX_Port*); + // Inserts/removes the specified port in to the group + // Returns 0, if successful; returns a negative value otherwise + + int operator == (const ACE_CLASSIX_Group &) const; + int operator != (const ACE_CLASSIX_Group &) const; + + // = HELPER + void dump(void) const; + + protected: + // = INITIALIZATION + ACE_CLASSIX_Group(); + // default constructor, does nothing but init. + + void init_(void); + // Initializes the structure. + + void set_config_(); + // Sets the group configured. + void clear_config_(); + // Sets the group not-configured. + + struct group_addr + { + int config_; // 1, if the following fields are valid + KnCap group_; + }; + group_addr addr_; + + private: + + // disable copy/assignment constructor + ACE_CLASSIX_Group(ACE_CLASSIX_Group const&); + ACE_CLASSIX_Group const& operator=(ACE_CLASSIX_Group const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Group.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_WRAPPER_CLASSIX_GROUP_H */ diff --git a/ace/CLASSIX/Group.i b/ace/CLASSIX/Group.i new file mode 100644 index 00000000000..e3650502a10 --- /dev/null +++ b/ace/CLASSIX/Group.i @@ -0,0 +1,89 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Group::ACE_CLASSIX_Group() + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Group::group_addr)) +{ + this->init_(); +} + +ACE_INLINE +ACE_CLASSIX_Group::ACE_CLASSIX_Group(void* theSrc, int theLen) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Group::group_addr)) +{ + this->set_addr(theSrc, theLen); +} + +ACE_INLINE +ACE_CLASSIX_Group::ACE_CLASSIX_Group(const KnCap& thePeer) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Group::group_addr)) +{ + this->set_addr(thePeer); +} + +ACE_INLINE +void * +ACE_CLASSIX_Group::get_addr(void) const +{ + return (void*) &this->addr_; +} + +ACE_INLINE +const KnUniqueId& +ACE_CLASSIX_Group::get_id(void) const +{ + return this->addr_.group_.ui; +} + +ACE_INLINE +int +ACE_CLASSIX_Group::is_configured(void) const +{ + return this->addr_.config_ == 1; +} + +ACE_INLINE +ACE_CLASSIX_Addr::Addr_Type +ACE_CLASSIX_Group::is_type(void) const +{ + return ACE_CLASSIX_Addr::GROUP; +} + +ACE_INLINE +void +ACE_CLASSIX_Group::set_config_(void) +{ + this->addr_.config_ = 1; +} + +ACE_INLINE +void +ACE_CLASSIX_Group::clear_config_(void) +{ + this->addr_.config_ = 0; +} + +ACE_INLINE +const KnCap& +ACE_CLASSIX_Group::get_cap(void) const +{ + return this->addr_.group_; +} + +ACE_INLINE +int +ACE_CLASSIX_Group::operator ==(const ACE_CLASSIX_Group & theRhs) const +{ + return + this->is_configured() && + theRhs.is_configured() && + ((KnCap) (this->get_cap()) == (KnCap) (theRhs.get_cap())); +} + +ACE_INLINE +int +ACE_CLASSIX_Group::operator !=(const ACE_CLASSIX_Group & theRhs) const +{ + return !(*this == theRhs); +} diff --git a/ace/CLASSIX/Group_Dynamic.cpp b/ace/CLASSIX/Group_Dynamic.cpp new file mode 100644 index 00000000000..af45fdc7e67 --- /dev/null +++ b/ace/CLASSIX/Group_Dynamic.cpp @@ -0,0 +1,24 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Group_Creator.cpp.1 +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Group_Dynamic.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Group_Dynamic.i" +#endif /* __ACE_INLINE__ */ diff --git a/ace/CLASSIX/Group_Dynamic.h b/ace/CLASSIX/Group_Dynamic.h new file mode 100644 index 00000000000..644236b620a --- /dev/null +++ b/ace/CLASSIX/Group_Dynamic.h @@ -0,0 +1,60 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Group_Dynamic.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_WRAPPER_CLASSIX_GROUP_DYNAMIC_H +#define ACE_WRAPPER_CLASSIX_GROUP_DYNAMIC_H + +/* ------------------------------------------------------------------------- */ +#include "CLASSIX/Group.h" + +class ACE_CLASSIX_Group_Dynamic : public ACE_CLASSIX_Group + // = TITLE + // Wrapper over Chorus's Group which is created dynamically and not named + // by a <Stamp>. + // + // = DESCRIPTION + // This is a subclass of <ACE_CLASSIX_Group>. + // + // Its encapsulated group is created dynamically and the + // <KnCap> is the name as well as the unique identifier. + // + // = SEE ALSO + // <ACE_CLASSIX_Group>, <ACE_CLASSIX_Group_Stamp> +{ + public: + + ACE_CLASSIX_Group_Dynamic(void); + // default constructor... create a group use Chorus IPC's K_DYNAMIC option + + virtual ACE_CLASSIX_Addr::Addr_Type is_type(void) const; + // returns Dynamic type + + private: + + ACE_CLASSIX_Group_Dynamic(ACE_CLASSIX_Group_Dynamic const&); + ACE_CLASSIX_Group_Dynamic const& operator=(ACE_CLASSIX_Group_Dynamic const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Group_Dynamic.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_WRAPPER_CLASSIX_GROUP_DYNAMIC_H */ diff --git a/ace/CLASSIX/Group_Dynamic.i b/ace/CLASSIX/Group_Dynamic.i new file mode 100644 index 00000000000..a7974ce45c1 --- /dev/null +++ b/ace/CLASSIX/Group_Dynamic.i @@ -0,0 +1,16 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Group_Dynamic::ACE_CLASSIX_Group_Dynamic(void) +{ + if (::grpAllocate( K_DYNAMIC, &this->addr_.group_, 0) == 0) + this->set_config_(); +} + +ACE_INLINE +ACE_CLASSIX_Addr::Addr_Type +ACE_CLASSIX_Group_Dynamic::is_type(void) const +{ + return ACE_CLASSIX_Addr::DYNAMIC; +} diff --git a/ace/CLASSIX/Group_Stamp.cpp b/ace/CLASSIX/Group_Stamp.cpp new file mode 100644 index 00000000000..990c5a05463 --- /dev/null +++ b/ace/CLASSIX/Group_Stamp.cpp @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Group_Stamp.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Group_Stamp.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Group_Stamp.i" +#endif /* __ACE_INLINE__ */ +/* ------------------------------------------------------------------------- */ +void +ACE_CLASSIX_Group_Stamp::set_addr(void* theStamp, int) +{ + // Get the group capability + this->stamp_ = *((u_int*)theStamp); + KnActorPrivilege actor; + actorPrivilege(K_MYACTOR, &actor, NULL); + if (::grpAllocate((actor == K_SUPACTOR) ? K_STATSYS : K_STATUSER, + &this->addr_.group_, + this->stamp_) < 0 ) + { + ACE_DEBUG((LM_DEBUG, "ACE_CLASSIX_Group_Stamp()::" + "group allocation failed\n")); + this->init_(); + this->stamp_ = ACE_CLASSIX_Group_Stamp::ILLEGAL_STAMP; + } + else + { + this->set_config_(); + } +} + +void +ACE_CLASSIX_Group_Stamp::dump(void) const +{ + ACE_DEBUG ((LM_DEBUG, "ACE_CLASSIX_Group_Stamp...\n")); + ACE_DEBUG ((LM_DEBUG, "\nStamp = %d\n", this->get_stamp())); + this->ACE_CLASSIX_Group::dump(); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/Group_Stamp.h b/ace/CLASSIX/Group_Stamp.h new file mode 100644 index 00000000000..f53b7accb98 --- /dev/null +++ b/ace/CLASSIX/Group_Stamp.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Group_Stamp.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_WRAPPER_CLASSIX_GROUP_STAMP_H +#define ACE_WRAPPER_CLASSIX_GROUP_STAMP_H + +/* ------------------------------------------------------------------------- */ +#include "CLASSIX/Group.h" + +class ACE_CLASSIX_Group_Stamp : public ACE_CLASSIX_Group + // = TITLE + // Wrapper over Chorus's Group using <Stamp> for naming the group. + // + // = DESCRIPTION + // This is a subclass of <ACE_CLASSIX_Group>. + // + // Its encapsulated group is named by a <stamp>. However, + // <KnCap> is still the unique identifier of the group. + // + // = NOTE + // As at the time of writing, The stamp is contained in the ui.uiTail + // field of <KnCap>. + // + // = SEE ALSO + // <ACE_CLASSIX_Group>, <ACE_CLASSIX_Group_Dynamic> + // +{ + public: + enum + { + ILLEGAL_STAMP = 0 + /* Have we defined the range of valid stamps? */ + }; + + // = INITIALIZATION + ACE_CLASSIX_Group_Stamp(); + // default constructor. Does not contain group information.. + ACE_CLASSIX_Group_Stamp(int /* stamp */); + // creates a group use the specfied stamp + virtual void set_addr(void*, /* pointer to the stamp */ + int = 0 /* not used */); + // Replaces the existing group according to the supplied stamp + + // = ACCESS + virtual ACE_CLASSIX_Addr::Addr_Type is_type(void) const; + // returns STAMP type + + int get_stamp() const; + // Returns the stamp + // If the address is not configured, the return value is unpredictable. + + // = HELPER + void dump(void) const; + + + + private: + u_int stamp_; + + // disable copy/assignment constructor + ACE_CLASSIX_Group_Stamp(ACE_CLASSIX_Group_Stamp const&); + ACE_CLASSIX_Group_Stamp const& operator=(ACE_CLASSIX_Group_Stamp const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Group_Stamp.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_WRAPPER_CLASSIX_GROUP_STAMP_H */ diff --git a/ace/CLASSIX/Group_Stamp.i b/ace/CLASSIX/Group_Stamp.i new file mode 100644 index 00000000000..0c03d8ab17a --- /dev/null +++ b/ace/CLASSIX/Group_Stamp.i @@ -0,0 +1,32 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Group_Stamp::ACE_CLASSIX_Group_Stamp() + : ACE_CLASSIX_Group (), + stamp_ (0) +{ +} + +ACE_INLINE +ACE_CLASSIX_Group_Stamp::ACE_CLASSIX_Group_Stamp(int theStamp) + : ACE_CLASSIX_Group () +{ + this->set_addr(&theStamp); +} + +ACE_INLINE +int +ACE_CLASSIX_Group_Stamp::get_stamp() const +{ + return this->stamp_; + +// return this->addr_.group_.ui.uiTail; +} + +ACE_INLINE +ACE_CLASSIX_Addr::Addr_Type +ACE_CLASSIX_Group_Stamp::is_type(void) const +{ + return ACE_CLASSIX_Addr::STAMP; +} diff --git a/ace/CLASSIX/OS.cpp b/ace/CLASSIX/OS.cpp new file mode 100644 index 00000000000..58225da3e51 --- /dev/null +++ b/ace/CLASSIX/OS.cpp @@ -0,0 +1,131 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX_OS.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/OS.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/OS.i" +#endif /* __ACE_INLINE__ */ + +#include "CLASSIX/Reactor.h" + +/* ------------------------------------------------------------------------- */ + +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_OS) +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_Msg) + +#if 0 +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_Mgr) +ACE_CLASSIX_Mgr::ACE_CLASSIX_Mgr(void) +{ +} + +ACE_CLASSIX_Mgr::~ACE_CLASSIX_Mgr(void) +{ +} + +ACE_SYNCH_RECURSIVE_MUTEXT& +ACE_CLASSIX_Mgr::ref_lock(void) const; +{ + return port_lock_; +} +#endif +/* ------------------------------------------------------------------------- */ +KnUniqueId ACE_CLASSIX_OS::null_KnUniqueId_; +ACE_Recursive_Thread_Mutex ACE_CLASSIX_OS::lock_; + +ACE_CLASSIX_OS::ACE_CLASSIX_OS(void) +{ + ACE_Reactor *r = + ACE_Reactor::instance + (new ACE_Reactor(new ACE_CLASSIX_Select_Reactor(), 1), 1); + + // Fills in a null KnUniqueId so that it can be referenced when required + this->null_KnUniqueId_.uiHead = this->null_KnUniqueId_.uiTail = 0; +} + +const KnUniqueId& +ACE_CLASSIX_OS::null_KnUniqueId(void) +{ + return null_KnUniqueId_; +} + + +ACE_Recursive_Thread_Mutex& +ACE_CLASSIX_OS::get_lock_(void) +{ + return lock_; +} + +ssize_t +ACE_CLASSIX_OS::convert_io_error(ssize_t theOriginal) +{ + switch (theOriginal) + { + case K_EFULL: + return ENOBUFS; + + case K_EINVAL: + return EFTYPE; + + case K_EFAULT: + return EFAULT; + + case K_ETOOMUCH: + return EMSGSIZE; + + case K_EUNKNOWN: + return EBADF; + + case K_ENOPORT: + return EBADF; + + case K_ETIMEOUT: + return ETIMEOUT; + + case K_EABORT: + return EINTR; + + default: + ACE_DEBUG((LM_DEBUG, "unknonw error: %d\n", theOriginal)); + return EFAULT; + } +} + + + +/* ------------------------------------------------------------------------- */ + +void +ACE_CLASSIX_Msg::dump(void) const +{ + ACE_DEBUG ((LM_INFO, ACE_BEGIN_DUMP, this)); + + char s[400]; + ACE_OS::sprintf (s, "flag = %x\n" + "body size = %d\t addr = %x\n" + "annex addr = %x\n" + "seq no = %d\n", + this->msg_.flags, + this->msg_.bodySize, this->msg_.bodyAddr, + this->msg_.annexAddr, + this->msg_.seqNum); + ACE_DEBUG ((LM_INFO, "%s", s)); + ACE_DEBUG ((LM_INFO, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/OS.h b/ace/CLASSIX/OS.h new file mode 100644 index 00000000000..b9c47eed4ec --- /dev/null +++ b/ace/CLASSIX/OS.h @@ -0,0 +1,129 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX_OS.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_CLASSIX_OS_H +#define ACE_CLASSIX_OS_H + +/* ------------------------------------------------------------------------- */ +#include "ace/OS.h" +#include "ace/Select_Reactor.h" +#include "ace/Singleton.h" +#include <ipc/chIpc.h> + +#include "CLASSIX/Port_Core.h" + +#if 0 +class ACE_Export ACE_CLASSIX_Mgr + // = TITLE + // Class to manage resouces, especially static resources + // + // = DESCRIPTION + // It is intended that one <ACE_CLASSIX_Mgr> per actor + // +{ + public: + friend ACE_Singleton<ACE_CLASSIX_Mgr, ACE_SYNCH_NULL_MUTEX>; + + ACE_SYNCH_RECURSIVE_MUTEXT& ref_lock(const) const; + + protected: + // = Initialization + ACE_CLASSIX_Mgr(void); + // Only allow its fried to instantiate, since it is meant as a + // singleton class. + // This class shall be instanti + +private: + ACE_SYNCH_RECURSIVE_MUTEX *port_lock_; +}; +#endif + +class ACE_Export ACE_CLASSIX_OS +{ +public: + + ACE_CLASSIX_OS(); + + static const KnUniqueId& null_KnUniqueId(); + static ssize_t convert_io_error (ssize_t /* CLASSIX' error no */); + // conver CLASSIX's errno no to Posix no. + +protected: + +private: + friend class ACE_CLASSIX_Port_Core; + friend class ACE_CLASSIX_Port; + static ACE_Recursive_Thread_Mutex& get_lock_(void); + // Returns CLASSIX environment-wide lock + + static KnUniqueId null_KnUniqueId_; + // Null-filled KnUniqueId + + static ACE_Recursive_Thread_Mutex lock_; +}; + +/* ------------------------------------------------------------------------- */ + + +class ACE_CLASSIX_Msg + // = TITLE + // Class wrapper over Chorus's KnMsgDesc structure + // + // = DESCRIPTION + // Provides initialization and reset methods to construct a KnMsgDesc. + // + // The flags in the <flags> field of the KnMsgDesc structure is always + // set to 0. Therefore, the message body will always be copied and + // the message is assumed to be part of the user(kernel) address + // space when the caller is a USER(SUPERVISOR) thread. + // (Chorus may not support the options defined in the flag, so we + // choose not to use the flag, i.e. set it to null). + // + // The message annex is not used. + + // = SEE ALSO + // ipcSend(2) +{ + public: + // = initialization + ACE_CLASSIX_Msg(); + // default constructor + ACE_CLASSIX_Msg(const void * /* body address */, int /* msg length */); + + KnMsgDesc* get(void); + // get CLASSIX' message structure + void set (const void* /* body address */, int /* msg length*/); + // Reset the message. The original message will be overwritten. + + void dump(void) const; + + ACE_ALLOC_HOOK_DECLARE; + // declare the dynamic allocation hooks + + private: + KnMsgDesc msg_; +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/OS.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_CLASSIX_OS_H */ diff --git a/ace/CLASSIX/OS.i b/ace/CLASSIX/OS.i new file mode 100644 index 00000000000..b32026eec80 --- /dev/null +++ b/ace/CLASSIX/OS.i @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Msg::ACE_CLASSIX_Msg(void) +{ + // Make a null-filled message + this->msg_.flags = 0; + this->msg_.bodySize = 0; + this->msg_.bodyAddr = 0; + this->msg_.annexAddr = 0; + this->msg_.seqNum = 0; +} + +ACE_INLINE +ACE_CLASSIX_Msg::ACE_CLASSIX_Msg(const void* theBuf, int theLen) +{ + this->msg_.flags = 0; + this->msg_.annexAddr = 0; + this->msg_.seqNum = 0; + + this->msg_.bodySize = theLen; + this->msg_.bodyAddr = (VmAddr) theBuf; +} + +ACE_INLINE +void +ACE_CLASSIX_Msg::set(const void* theBuf, int theLen) +{ + this->msg_.bodySize = theLen; + this->msg_.bodyAddr = (VmAddr) theBuf; +} + +ACE_INLINE +KnMsgDesc* +ACE_CLASSIX_Msg::get(void) +{ + return &this->msg_; +} diff --git a/ace/CLASSIX/Peer_SAP.cpp b/ace/CLASSIX/Peer_SAP.cpp new file mode 100644 index 00000000000..95f66045561 --- /dev/null +++ b/ace/CLASSIX/Peer_SAP.cpp @@ -0,0 +1,80 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// IPP +// +// = FILENAME +// CLASSIX/Peer_SAP.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Peer_SAP.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Peer_SAP.i" +#endif /* __ACE_INLINE__ */ + +#include "CLASSIX/Group_Stamp.h" +/* ------------------------------------------------------------------------- */ +int +ACE_CLASSIX_Peer_SAP::set(const ACE_CLASSIX_Port_Core& thePeer) +{ + delete this->peer_addr_; + this->peer_addr_ = new ACE_CLASSIX_Port (thePeer); + ACE_ASSERT(this->peer_addr_); + return 0; +} + +int +ACE_CLASSIX_Peer_SAP::set(const ACE_Addr& thePeer) +{ + delete this->peer_addr_; + this->peer_addr_ = new ACE_CLASSIX_Port (thePeer); + ACE_ASSERT(this->peer_addr_); + return 0; +} + +int +ACE_CLASSIX_Peer_SAP::set(const KnUniqueId& thePeer) +{ + delete this->peer_addr_; + this->peer_addr_ = new ACE_CLASSIX_Port (thePeer); + ACE_ASSERT(this->peer_addr_); + return 0; +} + +int +ACE_CLASSIX_Peer_SAP::set(const KnCap& thePeer) +{ + delete this->peer_addr_; + this->peer_addr_ = new ACE_CLASSIX_Group (thePeer); + ACE_ASSERT(this->peer_addr_); + return 0; +} + +int +ACE_CLASSIX_Peer_SAP::set(int theStamp) +{ + delete this->peer_addr_; + this->peer_addr_ = new ACE_CLASSIX_Group_Stamp (theStamp); + ACE_ASSERT(this->peer_addr_); + return 0; +} + +void +ACE_CLASSIX_Peer_SAP::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, "ACE_CLASSIX_Peer_SAP...\n")); + if (this->peer_addr_) + this->peer_addr_->dump(); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/Peer_SAP.h b/ace/CLASSIX/Peer_SAP.h new file mode 100644 index 00000000000..7246aa3be4e --- /dev/null +++ b/ace/CLASSIX/Peer_SAP.h @@ -0,0 +1,104 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// IPP +// +// = FILENAME +// CLASSIX/Peer_SAP.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef IPP_WRAPPER_CLASSIX_PEER_SAP_H +#define IPP_WRAPPER_CLASSIX_PEER_SAP_H + +/* ------------------------------------------------------------------------- */ +#include <CLASSIX/SAP.h> +#include <CLASSIX/Port_Default.h> + +class ACE_CLASSIX_Peer_SAP + // = TITLE + // Class implementing the peer SAP. + // + // = DESCRIPTION + // + // In CLASSIX, a local SAP is always a port, a peer SAP can be + // a port or a group of port. This class is for peer SAP and + // <ACE_SAP> is for local SAP. + // + // = SEE ALSO + // <ACE_SAP> +{ + public: + // = INITIALIZATION + ACE_CLASSIX_Peer_SAP(void); + // Default constructor. + // Needs to be initialized by a set() operation. + ACE_CLASSIX_Peer_SAP(const ACE_CLASSIX_Port_Core&);/* peer port */ + + ACE_CLASSIX_Peer_SAP(const ACE_CLASSIX_Port&);/* peer port address */ + ACE_CLASSIX_Peer_SAP(const ACE_Addr&); /* peer port address */ + + ACE_CLASSIX_Peer_SAP(const KnUniqueId&); /* peer port address */ + ACE_CLASSIX_Peer_SAP(const KnCap&); /* peer group address */ + ACE_CLASSIX_Peer_SAP(int /* stamp */); /* stamp for peer group */ + + ~ACE_CLASSIX_Peer_SAP(void); + + int set(const ACE_CLASSIX_Port_Core&); /* peer port */ + + int set(const ACE_Addr&); /* peer port address */ + + int set(const KnUniqueId&); /* peer port address */ + int set(const KnCap&); /* peer group address */ + int set(int /* stamp */); /* stamp for the peer group */ + + // = ACCESS + const ACE_CLASSIX_Addr* get_addr(void) const; + // Returns peer's address, either a port or a group of ports + int is_configured(void) const; + // Returns 1, if address information is proper; Returns 0 otherwise + + // = CONTROL +#if 0 + int control(u_int = K_BROADMODE); + int control(u_int, /* mode */ int /* site */ ); + // Interface for CLASSIX' send mode +#endif + // = HELPER + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + protected: +#if 0 + virtual set_mode_(u_int = K_BROADMODE); /* theMode */ + // Sets the addressing mode with the current setting of coTarget + virtual set_mode_(u_int, /* mode */ int /* site */); + // Sets the addressing mode as well as the coTarget +#endif + ACE_CLASSIX_Addr *peer_addr_; + + private: + // Disable copy constructor + ACE_CLASSIX_Peer_SAP(ACE_CLASSIX_Peer_SAP const&); + ACE_CLASSIX_Peer_SAP const& operator=(ACE_CLASSIX_Peer_SAP const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Peer_SAP.i" +#endif /* __ACE_INLINE__ */ + +#endif /* IPP_WRAPPER_CLASSIX_PEER_SAP_H */ diff --git a/ace/CLASSIX/Peer_SAP.i b/ace/CLASSIX/Peer_SAP.i new file mode 100644 index 00000000000..a10bcfd12b5 --- /dev/null +++ b/ace/CLASSIX/Peer_SAP.i @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Peer_SAP::ACE_CLASSIX_Peer_SAP(void) + : peer_addr_ (0) +{ +} + +ACE_INLINE +ACE_CLASSIX_Peer_SAP::ACE_CLASSIX_Peer_SAP(const ACE_CLASSIX_Port_Core& + thePeer) + : peer_addr_ (0) +{ + this->set(thePeer); +} + +ACE_INLINE +ACE_CLASSIX_Peer_SAP::ACE_CLASSIX_Peer_SAP(const ACE_CLASSIX_Port& thePeer) + : peer_addr_ (0) +{ + this->set(thePeer); +} + +ACE_INLINE +ACE_CLASSIX_Peer_SAP::ACE_CLASSIX_Peer_SAP(const ACE_Addr& thePeer) + : peer_addr_ (0) +{ + this->set(thePeer); +} + +ACE_INLINE +ACE_CLASSIX_Peer_SAP::ACE_CLASSIX_Peer_SAP(const KnUniqueId& thePeer) + : peer_addr_ (0) +{ + this->set(thePeer); +} + +ACE_INLINE +ACE_CLASSIX_Peer_SAP::ACE_CLASSIX_Peer_SAP(int theStamp) + : peer_addr_ (0) +{ + this->set(theStamp); +} + +ACE_INLINE +ACE_CLASSIX_Peer_SAP::~ACE_CLASSIX_Peer_SAP(void) +{ + delete this->peer_addr_; +} + + +ACE_INLINE +const ACE_CLASSIX_Addr* +ACE_CLASSIX_Peer_SAP::get_addr(void) const +{ + return this->peer_addr_; +} + +ACE_INLINE +int +ACE_CLASSIX_Peer_SAP::is_configured(void) const +{ + if (this->peer_addr_) + return this->peer_addr_->is_configured(); + else + return 0; +} + +#if 0 +ACE_INLINE +int +ACE_CLASSIX_Peer_SAP::control(u_int theMode) +{ + return this->peer_addr_->set_mode_(theMode); +} + +ACE_INLINE +int +ACE_CLASSIX_Peer_SAP::control(u_int theMode, int theSite) +{ + return this->set_mode_(theMode, theSite); +} + + +ACE_INLINE +int +ACE_CLASSIX_Peer_SAP::set_mode_(u_int) +{ + return K_EFAULT; +} + +ACE_INLINE +int +ACE_CLASSIX_Peer_SAP::set_mode_(u_int, int) +{ + return K_EFAULT; +} +#endif diff --git a/ace/CLASSIX/Port.cpp b/ace/CLASSIX/Port.cpp new file mode 100644 index 00000000000..f1e9203d531 --- /dev/null +++ b/ace/CLASSIX/Port.cpp @@ -0,0 +1,129 @@ +/* -*- C++ -*- */ +// $Id$ + +// Defines the ClassiX IPC address family address format. + +#define ACE_BUILD_DLL +#include "CLASSIX/Port.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Port.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_Port) + + +ACE_CLASSIX_Port::ACE_CLASSIX_Port(void* thePort, int theLen) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr)) +{ + if (thePort && theLen == this->get_size()) + { + ACE_CLASSIX_Port_Core::Addr *port = + (ACE_CLASSIX_Port_Core::Addr*) thePort; + this->addr_.handle = port->handle; + this->addr_.id = port->id; + } + else + { + this->clear(); + } +} + +ACE_CLASSIX_Port::ACE_CLASSIX_Port(ACE_Addr const& theAddr) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr)) +{ + if (theAddr.get_size() == this->get_size() && + theAddr.get_type() == this->get_type()) + this->set_(theAddr); + else + this->clear(); +} + +void +ACE_CLASSIX_Port::clear(void) +{ + this->addr_.handle = ACE_CLASSIX_ADDR_UNKNOWN; + this->addr_.id.uiHead = this->addr_.id.uiTail = 0; +} + +int +ACE_CLASSIX_Port::set_(const ACE_Addr& theAddr) +{ + ACE_CLASSIX_Port_Core::Addr *src = + ((ACE_CLASSIX_Port_Core::Addr*) theAddr.get_addr()); + this->addr_.id = src->id; + this->addr_.handle = src->handle; + + return 0; +} + +int +ACE_CLASSIX_Port::set(const KnUniqueId& thePort) +{ + int no = ::portLi((KnUniqueId*) &thePort); + + // update the port no only if the no is valid + if (no < 0) + // Assume this is a remote port + no = ACE_INVALID_HANDLE; + + this->addr_.handle = no; + this->addr_.id = thePort; + return 0; +} + +int +ACE_CLASSIX_Port::set_handle(ACE_HANDLE thePort) +{ + if (thePort == ACE_INVALID_HANDLE && + ::portUi(&this->addr_.id, thePort) < 0) + return -1; + + this->addr_.handle = thePort; + return 0; +} + +void +ACE_CLASSIX_Port::set_addr(void* theSrc, int theLen) +{ + // Remove self owned first and Make sure no memory overflow + if (theSrc && theLen > this->get_size()) + return; + + ACE_OS::memcpy ((void *) &this->addr_, + (void *) theSrc, theLen); + +} + +ACE_CLASSIX_Port const& +ACE_CLASSIX_Port::operator =(ACE_Addr const& theAddr) +{ + if (theAddr.get_size() == this->get_size() && + theAddr.get_type() == this->get_type()) + { + + this->set_(theAddr); + } + return *this; +} + +int +ACE_CLASSIX_Port::addr_to_string (ASYS_TCHAR s[], size_t) const +{ + ACE_OS::sprintf (s, ASYS_TEXT ("%d:%d"), + ASYS_WIDE_STRING (::agetId()), + this->get_port_number ()); +} + +void +ACE_CLASSIX_Port::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, "ACE_CLASSIX_Port...\n")); + ACE_Addr::dump(); + char s[100]; + ACE_OS::sprintf (s, "handle = %d;\tid head = %x, id tail = %x\n", + this->get_handle(), + this->get_id().uiHead, this->get_id().uiTail); + ACE_DEBUG ((LM_DEBUG, "%s", s)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/Port.h b/ace/CLASSIX/Port.h new file mode 100644 index 00000000000..db6acc9856d --- /dev/null +++ b/ace/CLASSIX/Port.h @@ -0,0 +1,158 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ipp_ace +// +// = FILENAME +// CLASSIX_Port.h +// +// = AUTHOR +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#if !defined (ACE_CLASSIX_PORT_H) +#define ACE_CLASSIX_PORT_H + +#include "ace/Singleton.h" +#include "CLASSIX/OS.h" +#include "CLASSIX/Addr.h" + + +class ACE_Export ACE_CLASSIX_Port : public ACE_CLASSIX_Addr +{ + // = TITLE + // Defines the ClassiX IPC Port address format for "ACE Socket" like + // interfaces + // + // = DESCRIPTION + // The port address contains two fields: + // a global unique identifier and a local identifier. + // The global unique identifier is also referred to as the port address + // and the local identifier as the port no. + // + // = NOTE + // In Chorus, one can always convert from a port unique identifier to + // a port no and vice versa. This class is implemented based on this + // premise. + // + // = SEE ALSO + // <ACE_CLASSIX_PORT_Default>, <ACE_CLASSIX_Port_Core> + // +public: + /* -----------------------------------------------------*/ + // = Initialization methods. + ACE_CLASSIX_Port (); + // Default constructor. + // The address corresponds to the default port of the actor. + + ACE_CLASSIX_Port (const ACE_CLASSIX_Port &); + // Copy constructor. + ACE_CLASSIX_Port (const ACE_Addr &); + // Copy constructor. + + ACE_CLASSIX_Port (const ACE_CLASSIX_Port_Core&); + // Creates an <ACE_CLASSIX_Port> from <ACE_CLASSIX_Port_Core> + + ACE_CLASSIX_Port (const KnUniqueId& /* port_id */); + // Creates an <ACE_CLASSIX_Port> from the given <port_id> + + ACE_CLASSIX_Port (ACE_HANDLE /* port_no */); + // Creates an <ACE_CLASSIX_Port> from the given <port_no> + + ACE_CLASSIX_Port (void* /* location */, int /* length */); + // Create an <ACE_CLASSIX_Port> from the address in raw format. + + ACE_CLASSIX_Port const& operator =(ACE_Addr const&); + + + /* -----------------------------------------------------*/ + // = ACCESS + + virtual int addr_to_string (ASYS_TCHAR addr[], size_t) const; + // Transform the current <ACE_CLASSIX_Port> address into string format, + // which is in the form "actor-id:port-number" + + int set (const KnUniqueId& /* port_id */); + // Sets the <ACE_CLASSIX_Port_Basic> from a <port_id> + + virtual void set_addr (void * /* addr location */, + int /* len */); + // Set the address as the one pointed to by the location pointer. + // The address contains <len> bytes. + // Would prefer to return the status, but the base class uses void. + int set_handle (ACE_HANDLE /* port_no */); + // Sets the <addr_> field from a <port_no> + + virtual void *get_addr (void) const; + // Returns a pointer to the address:, + // <ACE_CLASSIX_Port_Core::ipp_port_addr> + virtual const KnUniqueId& get_id (void) const; + // Returns a reference to the port id. + virtual ACE_HANDLE get_handle (void) const; + // Returns the port no. + int is_configured(void) const; + // Returns 1, if address information is proper; Returns 0 otherwise + virtual ACE_CLASSIX_Addr::Addr_Type is_type(void) const; + // returns PORT type + + /* -----------------------------------------------------*/ + // = Control + // + virtual int enable(int /* receive priority */) const; + // Puts the port into the set of monitored ports. + virtual int disable(void) const; + // Removes the port from the set of monitored ports. + virtual void clear(void); + // Remove port information + + /* -----------------------------------------------------*/ + // = Comparison + // + int operator == (const ACE_CLASSIX_Port &) const; + // Compare two addresses for equality. The addresses are considered + // equal if they have the same content in the KnUniqueId address structure. + + int operator != (const ACE_CLASSIX_Port &) const; + // Compare two addresses for inequality. + + /* -----------------------------------------------------*/ + // = Helper + // + void dump (void) const; + // Dump the state of an object. + + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + /* -----------------------------------------------------*/ + // = Direct initialization methods (useful after the object has been + // constructed). + // Will create/reset the port only if the port no was <ACE_CLASSIX_ANY> + // Returns 0 on success, -1 otherwise. + // + + int set_ (const ACE_Addr &); + // Sets the <ACE_CLASSIX_Port_Basic> from another <ACE_CLASSIX_Port_Basic>. + + + +private: + ACE_CLASSIX_Port_Core::Addr addr_; +}; + +/* ------------------------------------------------------------------------- */ +#if defined (__ACE_INLINE__) +#include "CLASSIX/Port.i" +#endif /* __ACE_INLINE__ */ + + +#endif /* ACE_CLASSIX_PORT_H */ diff --git a/ace/CLASSIX/Port.i b/ace/CLASSIX/Port.i new file mode 100644 index 00000000000..762f6ec5794 --- /dev/null +++ b/ace/CLASSIX/Port.i @@ -0,0 +1,112 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Port::ACE_CLASSIX_Port(void) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr)) +{ + this->set_handle(K_DEFAULTPORT); +} + +ACE_INLINE +ACE_CLASSIX_Port::ACE_CLASSIX_Port(const ACE_CLASSIX_Port& theSrc) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr)) +{ + this->set_(theSrc); +} + +ACE_INLINE +ACE_CLASSIX_Port::ACE_CLASSIX_Port(const KnUniqueId& thePort) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr)) +{ + this->set(thePort); +} + +ACE_INLINE +ACE_CLASSIX_Port::ACE_CLASSIX_Port(ACE_HANDLE thePort) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr)) +{ + this->set_handle(thePort); +} + +ACE_INLINE +ACE_CLASSIX_Port::ACE_CLASSIX_Port(const ACE_CLASSIX_Port_Core& thePort) + : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr)) +{ + this->addr_.handle = thePort.get_handle(); + this->addr_.id = thePort.get_id(); +} + +ACE_INLINE +ACE_HANDLE +ACE_CLASSIX_Port::get_handle(void) const +{ + return this->addr_.handle; +} + +ACE_INLINE +const KnUniqueId& +ACE_CLASSIX_Port::get_id(void) const +{ + return this->addr_.id; +} + +ACE_INLINE +void * +ACE_CLASSIX_Port::get_addr(void) const +{ + return (void*) &this->addr_; +} + +ACE_INLINE +int +ACE_CLASSIX_Port::is_configured(void) const +{ + return (this->addr_.handle != ACE_CLASSIX_ADDR_UNKNOWN); +} + +ACE_INLINE +ACE_CLASSIX_Addr::Addr_Type +ACE_CLASSIX_Port::is_type(void) const +{ + return ACE_CLASSIX_Addr::PORT; +} + +ACE_INLINE +int +ACE_CLASSIX_Port::enable(int thePriority) const +{ + if (ACE_Reactor::instance()->notify() == 0) + return ::portEnable(K_MYACTOR, this->get_handle(), thePriority); + else + return -1; +} + +ACE_INLINE +int +ACE_CLASSIX_Port::disable(void) const +{ + if (ACE_Reactor::instance()->notify() == 0) + return ::portDisable(K_MYACTOR, this->get_handle()); + else + return -1; +} + +// Compare two addresses for equality. +ACE_INLINE +int +ACE_CLASSIX_Port::operator==(const ACE_CLASSIX_Port &theSrc) const +{ + return + this->ACE_Addr::operator == (theSrc) && + this->addr_.id.uiHead == theSrc.addr_.id.uiHead && + this->addr_.id.uiTail == theSrc.addr_.id.uiTail && + this->addr_.handle == theSrc.addr_.handle; +} + +ACE_INLINE +int +ACE_CLASSIX_Port::operator != (const ACE_CLASSIX_Port &sap) const +{ + return !((*this) == sap); +} diff --git a/ace/CLASSIX/Port_Core.cpp b/ace/CLASSIX/Port_Core.cpp new file mode 100644 index 00000000000..9f5eacd3d1b --- /dev/null +++ b/ace/CLASSIX/Port_Core.cpp @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Port_Core.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Port_Core.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Port_Core.i" +#endif /* __ACE_INLINE__ */ + +#include "ace/Synch_T.h" +#include "CLASSIX/OS.h" +/* ------------------------------------------------------------------------- */ + +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_Port_Core) + +ACE_CLASSIX_Port_Core::ACE_CLASSIX_Port_Core(void) +{ + if ((this->addr_.handle = ::portCreate(K_MYACTOR, &this->addr_.id)) < 0) + this->clear_config_(); + else + { + this->set_config_(); + } +} + +ACE_CLASSIX_Port_Core::~ACE_CLASSIX_Port_Core(void) +{ + if (this->is_configured()) + if (int result = ::portDelete(K_MYACTOR, this->get_handle()) < 0) + ACE_ERROR((LM_DEBUG, + "ACE_CLASSIX_Port_Core::~ACE_CLASSIX_PORT_CORE()- " + "failed to delete port, error = %d", result)); +} + +void +ACE_CLASSIX_Port_Core::clear_config_(void) +{ + this->config_ = 0; + this->addr_.id.uiHead = this->addr_.id.uiTail = 0; + this->addr_.handle = ACE_INVALID_HANDLE; +} + + +void +ACE_CLASSIX_Port_Core::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, "ACE_CLASSIX_Port_Core...\n")); + char s[100]; + if (!this->is_configured()) + ACE_OS::sprintf(s, "Port has not been allocated\n"); + else + ACE_OS::sprintf (s, "handle = %d;\tid head = %x, id tail = %x\n", + this->get_handle(), + this->get_id().uiHead, this->get_id().uiTail); + ACE_DEBUG ((LM_DEBUG, "%s", s)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/Port_Core.h b/ace/CLASSIX/Port_Core.h new file mode 100644 index 00000000000..8b8fb74f46c --- /dev/null +++ b/ace/CLASSIX/Port_Core.h @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Port_Core.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_CLASSIX_PORT_CORE_H +#define ACE_CLASSIX_PORT_CORE_H + +/* ------------------------------------------------------------------------- */ +#include "ace/OS.h" +#include <ipc/chIpc.h> + + +/* ------------------------------------------------------------------------- */ +class ACE_Export ACE_CLASSIX_Port_Core +{ + // = TITLE + // Defines interfaces for allocation/deallocation of a Chorus + // IPC port + // + // = DESCRIPTION + // This class allocates a port in the constructor and deallocates it in + // the destructor. + +public: + /* -----------------------------------------------------*/ + // = Initialization methods. + ACE_CLASSIX_Port_Core (void); + // Allocates a port from the OS + // + virtual ~ACE_CLASSIX_Port_Core (void); + // Deallocates the port from the OS. + + virtual const KnUniqueId& get_id (void) const; + // Returns a reference to the port id. + virtual ACE_HANDLE get_handle (void) const; + // Returns the port no(used as an ACE_HANDLE) + virtual void* get_addr(void) const; + // Returns a pointer to the location containing the raw + // address of the port. + int is_configured(void) const; + // Returns 1, if the port has been successfully created. + +#if 0 + int enable(int /* priority */) const; + int disable (int) const; + // Puts/Removes the port into/from the set of monitored ports. +#endif + /* -----------------------------------------------------*/ + // = Helper + // + void dump (void) const; + // Dump the state of an object. + + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + struct Addr + { + KnUniqueId id; // port address: unique identifier + ACE_HANDLE handle;// port no: local identifier. + + }; + +protected: + void clear_config_(); + // Indicates that port has been allocated. + void set_config_(); + + ACE_CLASSIX_Port_Core::Addr addr_; + int config_; // Sets to 1, if configured; + // 0 otherwise +private: + // Disallow copy constructor/assignment + ACE_CLASSIX_Port_Core(ACE_CLASSIX_Port_Core const&); + ACE_CLASSIX_Port_Core const& operator =(ACE_CLASSIX_Port_Core const&); +}; +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Port_Core.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_CLASSIX_PORT_CORE_H */ diff --git a/ace/CLASSIX/Port_Core.i b/ace/CLASSIX/Port_Core.i new file mode 100644 index 00000000000..7fd3694d8de --- /dev/null +++ b/ace/CLASSIX/Port_Core.i @@ -0,0 +1,38 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +void +ACE_CLASSIX_Port_Core::set_config_(void) +{ + this->config_ = 1; +} + +ACE_INLINE +int +ACE_CLASSIX_Port_Core::is_configured(void) const +{ + return this->config_ == 1; +} + + +ACE_INLINE +ACE_HANDLE +ACE_CLASSIX_Port_Core::get_handle(void) const +{ + return this->addr_.handle; +} + +ACE_INLINE +const KnUniqueId& +ACE_CLASSIX_Port_Core::get_id(void) const +{ + return this->addr_.id; +} + +ACE_INLINE +void* +ACE_CLASSIX_Port_Core::get_addr(void) const +{ + return (void*) (&this->addr_); +} diff --git a/ace/CLASSIX/Port_Default.cpp b/ace/CLASSIX/Port_Default.cpp new file mode 100644 index 00000000000..53e3ef737a3 --- /dev/null +++ b/ace/CLASSIX/Port_Default.cpp @@ -0,0 +1,26 @@ +/* -*- C++ -*- */ +// $Id$ + +// Defines the ClassiX IPC address family address format. + +#define ACE_BUILD_DLL +#include "CLASSIX/Port_Default.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Port_Default.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_Port_Default) + +/* ------------------------------------------------------------------------- */ +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Singleton<ACE_CLASSIX_Port_Default, + ACE_SYNCH_NULL_MUTEX>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiation ACE_Singleton<ACE_CLASSIX_Port_Default, + ACE_SYNCH_NULL_MUTEX> + +#endif diff --git a/ace/CLASSIX/Port_Default.h b/ace/CLASSIX/Port_Default.h new file mode 100644 index 00000000000..f7d64d08a1e --- /dev/null +++ b/ace/CLASSIX/Port_Default.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ipp_ace +// +// = FILENAME +// CLASSIX/Port_Default.h +// +// = AUTHOR +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#if !defined (ACE_CLASSIX_PORT_DEFAULT_H) +#define ACE_CLASSIX_PORT_DEFAULT_H + +#include "ace/Singleton.h" +#include "CLASSIX/Port.h" + +class ACE_CLASSIX_Port_Default : public ACE_CLASSIX_Port +{ + // = TITLE + // Implements the address wrapper of an actor's default port. + // + // = DESCRIPTION + // This corresponds to the address of an actor's default port + // which does not change + // in the life time of the actor. Therefore the address information + // in this class can not be modified once it is created. + // + // Each actor has one and only one default port. Therefore an instance + // of this class is a singleton. The protected constructor and the + // friendship with the ACE_Singleton preventys this class from being + // instantiated by other classes. + // + // = NOTE + // + // = SEE ALSO + // <ACE_CLASSIX_PORT> + // + friend class ACE_Singleton<ACE_CLASSIX_Port_Default, ACE_SYNCH_NULL_MUTEX>; + + /* -----------------------------------------------------*/ + // = Access + virtual void set_addr(void*, int); + ACE_CLASSIX_Port const& operator =(ACE_CLASSIX_Port const&); + ACE_CLASSIX_Port const& operator =(ACE_Addr const&); + // Does nothing...The default port's address cannot be changed + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + /* -----------------------------------------------------*/ + // = Initialization methods. + ACE_CLASSIX_Port_Default (); + // Wrapper for the Actor's default port +}; + + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Port_Default.i" +#endif /* __ACE_INLINE__ */ + +/* ------------------------------------------------------------------------- */ +typedef ACE_Singleton<ACE_CLASSIX_Port_Default, ACE_SYNCH_NULL_MUTEX> + ACE_CLASSIX_DEFAULT_PORT; +/* ------------------------------------------------------------------------- */ + +#endif /* ACE_CLASSIX_PORT_DEFAULT_H */ diff --git a/ace/CLASSIX/Port_Default.i b/ace/CLASSIX/Port_Default.i new file mode 100644 index 00000000000..fac497bace0 --- /dev/null +++ b/ace/CLASSIX/Port_Default.i @@ -0,0 +1,28 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Port_Default::ACE_CLASSIX_Port_Default(void) + : ACE_CLASSIX_Port() +{ +} + +ACE_INLINE +void +ACE_CLASSIX_Port_Default::set_addr(void*, int) +{ +} + +ACE_INLINE +ACE_CLASSIX_Port const& +ACE_CLASSIX_Port_Default::operator =(ACE_CLASSIX_Port const&) +{ + return *this; +} + +ACE_INLINE +ACE_CLASSIX_Port const& +ACE_CLASSIX_Port_Default::operator =(ACE_Addr const&) +{ + return *this; +} diff --git a/ace/CLASSIX/SAP.cpp b/ace/CLASSIX/SAP.cpp new file mode 100644 index 00000000000..d876498ffb7 --- /dev/null +++ b/ace/CLASSIX/SAP.cpp @@ -0,0 +1,156 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX_SAP.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 ??? +// +// ============================================================================ + +#include "CLASSIX/SAP.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/SAP.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_CLASSIX_SAP) +/* ------------------------------------------------------------------------- */ +int +ACE_CLASSIX_SAP::get_addr(ACE_Addr& theAddr) const +{ + if (theAddr.get_size() < this->local_addr_.get_size() || + theAddr.get_type() != this->local_addr_.get_type()) + { + return -1; + } + else + { + theAddr.set_addr(this->local_addr_.get_addr(), + this->local_addr_.get_size()); + return 0; + } +} + +void +ACE_CLASSIX_SAP::set_addr(const ACE_Addr& theAddr) +{ + this->local_addr_.set_addr(theAddr.get_addr(), theAddr.get_size()); +} + + +void +ACE_CLASSIX_SAP::set_addr(const ACE_CLASSIX_Port_Core& thePort) +{ + this->local_addr_.set_addr(thePort.get_addr(), + sizeof (ACE_CLASSIX_Port_Core::Addr)); +} + +int +ACE_CLASSIX_SAP::set(const KnUniqueId& theId) +{ + return this->local_addr_.set(theId); +} + +void +ACE_CLASSIX_SAP::set_handle(ACE_HANDLE theHandle) +{ + if (this->local_addr_.set_handle(theHandle) == -1) + ACE_DEBUG((LM_DEBUG, "ACE_CLASSIX_SAP::set_handle()::" + "Handle invalid\n")); +} + +int +ACE_CLASSIX_SAP::set(const ACE_Addr& theAddr) +{ + this->set_addr(theAddr); + return 0; +} + +int +ACE_CLASSIX_SAP::open(const ACE_Addr& theAddr) +{ + this->set_addr(theAddr); + return 0; +} + + +int +ACE_CLASSIX_SAP::set(const ACE_CLASSIX_Port_Core& thePort) +{ + this->set_addr(thePort); + return 0; +} + + +int +ACE_CLASSIX_SAP::open(const ACE_CLASSIX_Port_Core* thePort) +{ + if (thePort) + { + this->set_addr(ACE_CLASSIX_Port(*thePort)); + return 0; + } + else + return -1; +} + +int +ACE_CLASSIX_SAP::close(void) +{ + // Disable receiving + this->unselectable(); + //*** Do something to flush out potential messages on the local port + // e.g. have a separte thread call ipcReceive on each disabled SAP. + + this->local_addr_.clear(); + return 0; +} + +int +ACE_CLASSIX_SAP::selectable(int thePriority) +{ + if (!this->enabled_) + { + int result = this->local_addr_.enable(thePriority); + if (result == 0) + this->enabled_ = 1; + return result; + } + else + return 0; +} + +int +ACE_CLASSIX_SAP::unselectable(int) +{ + if (this->enabled_) + { + int result = this->local_addr_.disable(); + if (result == 0) + this->enabled_ = 0; + return result; + } + else + return 0; +} + + +void +ACE_CLASSIX_SAP::dump(void) const +{ + ACE_DEBUG ((LM_INFO, "ACE_CLASSIX_SAP...\n")); + + this->local_addr_.dump(); + + ACE_DEBUG ((LM_INFO, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/SAP.h b/ace/CLASSIX/SAP.h new file mode 100644 index 00000000000..749b8b72fff --- /dev/null +++ b/ace/CLASSIX/SAP.h @@ -0,0 +1,142 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX_SAP.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_CLASSIX_SAP_H +#define ACE_CLASSIX_SAP_H + +/* ------------------------------------------------------------------------- */ +#include "CLASSIX/Port.h" + +class ACE_CLASSIX_SAP + // = TITLE + // Class implementing the SAP over a Chorus port. + // + // = DESCRIPTION + // A SAP has a port which is referred to as the local port. + // This class provides methods to manipulate this port. + // + // The SAP will always put the port in DISABLED state on exit. + // + // In CLASSIX, a local SAP is always a port, a peer SAP can be + // a port or a group of port. This class is for local SAP and + // <ACE_Peer_SAP> is for peer SAP. + // + // = SEE ALSO + // <ACE_Peer_SAP> + // +{ + public: + enum + { + DEFAULT_PRIORITY = 10 + }; + + // = INITIALIZATION + ACE_CLASSIX_SAP(void); + // Creates a SAP, using the address of the actor's default port. + ACE_CLASSIX_SAP(const ACE_Addr&); + // Creates a SAP, using the specified address as the local address. + virtual ~ACE_CLASSIX_SAP(void); + + // = ACCESS + void set_addr(const ACE_Addr&); + void set_addr(const ACE_CLASSIX_Port_Core&); + // Sets the <local_addr_> based on the given address information. + // The caller should make sure that the original address can be removed! + int set(const ACE_Addr&); + // Returns 0, if successful; returns -1, otherwise + // same as set_addr(const ACE_Addr&); + int set(const ACE_CLASSIX_Port_Core&); + // Returns 0, if successful; returns -1, otherwise + // same as void set_addr(const ACE_CLASSIX_Port_Core&); + int set (const KnUniqueId&); + // Returns 0, if successful; returns -1, otherwise + + void set_handle (ACE_HANDLE /* port_no */); + // Sets the port address according to <port_no> + + int get_addr(ACE_Addr& /* return_addr */) const; + // Returns address information to the supplied location. + // if successful, return 0 and the return_addr parameter contains the + // address info. + // Otherwise, return -1 + const ACE_CLASSIX_Port& get_addr(void) const; + // Returns a reference to the address information + ACE_HANDLE get_handle(void) const; + // Get handles that the Reactor uses + virtual int is_configured(void) const; + // Returns 1, if address information is proper; Returns 0 otherwise + int is_selectable(void) const; + // Retruns 1, if the local SAP is enabled. + + // = CONTROL + int selectable(int = ACE_CLASSIX_SAP::DEFAULT_PRIORITY /* priority */); + // Puts the SAP in the ENABLED state so that data the port associated + // with its local addess can be monitored by the CLASSIX's Reactor. + + int unselectable(int = 0 /* not used */); + // Makes the SAP DISABLED and therefore the SAP can not be monitored + // by the CLASSIX's Reactor.. + int open(const ACE_Addr&); + int open(const ACE_CLASSIX_Port_Core*); + // Sets the address information according to the supplied port + // Returns 0 on success; returns -1 otherwise + int close(void); + // removes the port information + // Returns 0 on success (always); returns -1 otherwise + + void clear(void); + // erase local port info + +#if 0 + int control(u_int = K_BROADMODE); + int control(u_int, /* mode */ int /* site */ ); + // Interface for CLASSIX' send mode +#endif + + + // = HELPER + void dump(void) const; + // dump the state of an object + + ACE_ALLOC_HOOK_DECLARE; + // declare the dynamic allocation hooks + + protected: +#if 0 + virtual set_mode_(u_int = K_BROADMODE); /* theMode */ + // Sets the addressing mode with the current setting of coTarget + virtual set_mode_(u_int, /* mode */ int /* site */); + // Sets the addressing mode as well as the coTarget +#endif + // Disable copy constructor/assignment + ACE_CLASSIX_SAP(ACE_CLASSIX_SAP const&); + ACE_CLASSIX_SAP const& operator=(ACE_CLASSIX_SAP const&); + + ACE_CLASSIX_Port local_addr_; + int enabled_; // 1 if enabled, 0 if disabled (Default) +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/SAP.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_CLASSIX_SAP_H */ diff --git a/ace/CLASSIX/SAP.i b/ace/CLASSIX/SAP.i new file mode 100644 index 00000000000..105570b363b --- /dev/null +++ b/ace/CLASSIX/SAP.i @@ -0,0 +1,58 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_SAP::ACE_CLASSIX_SAP(void) + :local_addr_ (), + enabled_ (0) +{ +} + +ACE_INLINE +ACE_CLASSIX_SAP::ACE_CLASSIX_SAP(const ACE_Addr& theAddr) + :local_addr_ (theAddr.get_addr(), theAddr.get_size()), + enabled_ (0) +{ +} + +ACE_INLINE +ACE_CLASSIX_SAP::~ACE_CLASSIX_SAP(void) +{ + this->unselectable(); +} + +ACE_INLINE +const ACE_CLASSIX_Port& +ACE_CLASSIX_SAP::get_addr(void) const +{ + return this->local_addr_; +} + + +ACE_INLINE +ACE_HANDLE +ACE_CLASSIX_SAP::get_handle(void) const +{ + return this->local_addr_.get_handle(); +} + +ACE_INLINE +int +ACE_CLASSIX_SAP::is_configured(void) const +{ + return this->local_addr_.is_configured(); +} + +ACE_INLINE +int +ACE_CLASSIX_SAP::is_selectable(void) const +{ + return this->enabled_ == 1; +} + +ACE_INLINE +void +ACE_CLASSIX_SAP::clear(void) +{ + this->local_addr_.clear(); +} diff --git a/ace/CLASSIX/Select_Reactor.cpp b/ace/CLASSIX/Select_Reactor.cpp new file mode 100644 index 00000000000..50ddfbaf5da --- /dev/null +++ b/ace/CLASSIX/Select_Reactor.cpp @@ -0,0 +1,440 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Reactor.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Reactor.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Reactor.i" +#endif /* __ACE_INLINE__ */ + +#include "CLASSIX/OS.h" +/* ------------------------------------------------------------------------- */ +ACE_CLASSIX_Select_Reactor::ACE_CLASSIX_Select_Reactor( + ACE_Timer_Queue *theTimeQ) + : ACE_Select_Reactor(0, theTimeQ, 0, + new ACE_CLASSIX_Select_Reactor_Notify()), + current_msg_size_ (0), + current_handle_ (ACE_INVALID_HANDLE) +{ +} + +ACE_CLASSIX_Select_Reactor::ACE_CLASSIX_Select_Reactor ( + size_t theSize, + int theRs, + ACE_Timer_Queue *theTimeQ) + : ACE_Select_Reactor (theSize, theRs, 0, theTimeQ, 0, + new ACE_CLASSIX_Select_Reactor_Notify() ), + current_msg_size_ (0), + current_handle_ (ACE_INVALID_HANDLE) +{ +} + +int +ACE_CLASSIX_Select_Reactor::wait_for_multiple_events + (ACE_Select_Reactor_Handle_Set &theDispatchSet, + ACE_Time_Value *max_wait_time) +{ + + ACE_Time_Value timer_buf (0); + ACE_Time_Value *this_timeout = &timer_buf; + + int number_of_active_handles = this->any_ready (theDispatchSet); + + // If there are any bits enabled in the <ready_set_> then we'll + // handle those first, otherwise we'll block in select(). + + if (number_of_active_handles == 0) + { + int port = K_ANYENABLED; + do + { + // Monitor all enabled ports + // CLASSIX uses -1 rathre than 0 for blocked receive + int msec = -1; + if (this->timer_queue_->calculate_timeout (max_wait_time, + this_timeout) != 0) + { + if ((msec = this_timeout->msec()) == 0) + { + msec = -1; + this_timeout = 0; + } + } + else + this_timeout = 0; + + ACE_CLASSIX_Msg rmsg(0, 0); + port = K_ANYENABLED; + ssize_t size = ::ipcReceive(rmsg.get(), &port, msec); +#if 0 + ACE_DEBUG((LM_DEBUG, + "(%t)ACE_CLASSIX_Select_Reactor::" + "return from ipcReceive():ret = %d" + ", port = %d, timeout = %d\n", + size, port, msec)); +#endif + if (size >= 0) + { + // Is 0 valid ??? + // Keep info about which handler this message is for and + // its size. + if (this->set_current_info_(port, size) == 0) + { + theDispatchSet.rd_mask_.set_bit(port); + number_of_active_handles = 1; + } + else + { + ACE_DEBUG((LM_DEBUG, + "Synchronization problem in Reactor???\n")); + number_of_active_handles = -1; + errno = K_EFAULT; + } + } + else + { + // make the current message information invalid + this->set_current_info_(ACE_INVALID_HANDLE, 0); + if ((errno = size) == K_ETIMEOUT) + number_of_active_handles = 0; + else + number_of_active_handles = -1; + } + } + while (number_of_active_handles == -1 && + this->handle_error_ (port) > 0); + } + // Return the number of events to dispatch. + return number_of_active_handles; +} + +int +ACE_CLASSIX_Select_Reactor::set_current_info_(ACE_HANDLE thePort, + size_t theSize) +{ +// ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, +// this->current_lock_, -1)); + ACE_MT(ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, + this->token_, -1)); + + this->current_handle_ = thePort; + this->current_msg_size_ = theSize; + return 0; +} + +int +ACE_CLASSIX_Select_Reactor::get_current_info(ACE_HANDLE thePort, + size_t& theSize) +{ +// ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, +// this->current_lock_, 0)); + ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, + ace_mon, this->token_, -1)); + + if (this->current_handle_ == thePort) + { + theSize = this->current_msg_size_; + this->current_msg_size_ = 0; + this->current_handle_ = ACE_INVALID_HANDLE; + return 0; + } + else + { + theSize = 0; + return -1; + } +} + +#if 0 +ACE_Message_Block* +ACE_CLASSIX_Select_Reactor::collect_msg(ACE_HANDLE theHandle) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + this->lock_current_, 0)); + + if (this->current_handle_ != ACE_INVALID_HANDLE && + theHandle == this->current_handle_) + { + ACE_Message_Block *msg = this->current_msg_; + this->current_msg_ = 0; + this->current_handle_ = ACE_INVALID_HANDLE; + return msg; + } + else + { + return 0; + } +} + + +int +ACE_CLASSIX_Select_Reactor::get_data_(ACE_HANDLE theHandle, size_t theSize) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + this->lock_current_, 0)); + + // reset current information + this->current_error_ = 0; + this->current_handle_= theHandle; + + // Remove the previous message that has not been taken + if (this->current_msg_) + this->current_msg_->release(); + + // Read the current message into a block bigger than the actual size + // to facilitate adding potential paddings by the handler + this->current_msg_ = new ACE_Message_Block(theSize + this->overhead_); + char *data = this->current_msg_ == 0 ? 0 : this->current_msg_->rd_ptr(); + // Invoke the read operation even though we may not have a buffer for it. + // This is to clean up the CLASSIX' current message space. + ACE_CLASSIX_Msg rmsg(data, data == 0 ? 0 : theSize); + int result = ::ipcGetData(rmsg.get()); + + if (!this->current_msg_) + this->current_error_ = ENOBUFS; + else if (result < 0) + this->current_error_ = ACE_CLASSIX_OS::convert_io_error(result); + else if (result != theSize) + this->current_error_ = EFAULT; + + if (this->current_error_ < 0 && this->current_msg_) + { + this->current_msg_->release(); + this->current_msg_ = 0; + } + return this->current_error_; +} +#endif + +int +ACE_CLASSIX_Select_Reactor::handle_error_ (int thePort) +{ + + // The thread has been aborted + if (errno == K_EABORT) + return this->restart_; + // No port or a (Chorus) handler is attached to the port + else if (errno == K_ENOPORT || errno == K_EINVAL) + return this->check_handles_ (thePort); + else + return -1; +} + +int +ACE_CLASSIX_Select_Reactor::check_handles_ (int thePort) +{ + ACE_TRACE ("ACE_Select_Reactor::check_handles"); + if (thePort == K_ANYENABLED) + return -1; + else + // Don't know how to check if a Chorus port has been disabled or deleted. + return 0; +} + +/* ------------------------------------------------------------------------- */ + +ACE_CLASSIX_Select_Reactor_Notify::ACE_CLASSIX_Select_Reactor_Notify(void) + : ACE_Select_Reactor_Notify() +{ + // Get the address for the notification port + // this->notification_sap_.set_addr + // (ACE_CLASSIX_Port(this->notification_port_)); +} + +void +ACE_CLASSIX_Select_Reactor_Notify::dump (void) const +{ + ACE_TRACE ("ACE_CLASSIX_Select_Reactor_Notify::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("CLASSIX_select_reactor_ = %x"), + this->select_reactor_)); + this->notification_sap_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_CLASSIX_Select_Reactor_Notify::open (ACE_Select_Reactor *r, + int disable_notify_pipe) +{ + if (disable_notify_pipe == 0) + { + this->select_reactor_ = r; + + if (this->notification_sap_.open (&this->notification_port_) != 0 || + this->notification_sap_.selectable() != 0) + return -1; + + return this->select_reactor_->register_handler + (this->notification_sap_.get_handle (), + this, + ACE_Event_Handler::READ_MASK); + } + else + { + this->select_reactor_ = 0; + } +} + +int +ACE_CLASSIX_Select_Reactor_Notify::close (void) +{ + ACE_TRACE ("ACE_Select_Reactor_Notify::close"); + // deregister handle ??? + return this->notification_sap_.close (); +} + +ssize_t +ACE_CLASSIX_Select_Reactor_Notify::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask, + ACE_Time_Value *timeout) +{ + ACE_Notification_Buffer buffer (eh, mask); + ACE_CLASSIX_Msg msg(&buffer, sizeof (buffer)); + KnIpcDest dest; + dest.target = this->notification_sap_.get_addr().get_id(); + + ssize_t n = ipcSend (msg.get(), K_DEFAULTPORT, &dest); + if (n < 0) + ACE_DEBUG((LM_DEBUG, "ipcSend() error = %d\n", n)); + return n == 0 ? 0 : -1; +} + +// Handles pending threads (if any) that are waiting to unblock the +// Select_Reactor. + +int +ACE_CLASSIX_Select_Reactor_Notify::dispatch_notifications ( + int & number_of_active_handles, + const ACE_Handle_Set &rd_mask) +{ + ACE_TRACE ("(%t) ACE_Select_Reactor_Notify::handle_notification"); + + ACE_HANDLE read_handle = + this->notification_sap_.get_handle (); + + if (rd_mask.is_set (read_handle)) + { + number_of_active_handles--; + return this->handle_input (read_handle); + } + else + return 0; +} + +// Special trick to unblock select() when updates occur in somewhere +// other than the main ACE_Select_Reactor thread. All we do is write data to +// a pipe that the ACE_Select_Reactor is listening on. Thanks to Paul +// Stephenson for suggesting this approach. + +int +ACE_CLASSIX_Select_Reactor_Notify::handle_input (ACE_HANDLE handle) +{ + // Precondition: this->select_reactor_.token_.current_owner () == + // ACE_Thread::self (); + + if (handle != this->notification_sap_.get_handle()) + { + ACE_DEBUG((LM_DEBUG, "ACE_CLASSIX_Select_Reator_Notify::" + "handle_input() Not my handle\n")); + return 0; + } + + ssize_t n = 0; + size_t n1= 0; + + int number_dispatched = 0; + + ACE_Notification_Buffer buffer; + ACE_CLASSIX_Msg rmsg(&buffer, sizeof (buffer)); + + if (this->select_reactor_->get_current_info(handle, n1) == -1 || + n1 != sizeof buffer) + { + // I'm not sure quite what to do at this point. It's + // probably best just to return -1. + ACE_DEBUG((LM_DEBUG, + "ACE_CLASSIX_Select_Reactor_Notify:: " + "read not expected by the reactor\n", n1)); + return -1; + } + + while ((n = ::ipcGetData(rmsg.get())) > 0) + { + if (n != sizeof buffer) + { + // I'm not sure quite what to do at this point. It's + // probably best just to return -1. + ACE_DEBUG((LM_DEBUG, + "ACE_CLASSIX_Select_Reactor_Notify::ipcGetDAta() " + "incorrect read(%d)\n", n)); + return -1; + } + + // If eh == 0 then another thread is unblocking the ACE_Select_Reactor + // to update the ACE_Select_Reactor's internal structures. Otherwise, + // we need to dispatch the appropriate handle_* method on the + // ACE_Event_Handler pointer we've been passed. + if (buffer.eh_ != 0) + { + int result = 0; + + switch (buffer.mask_) + { + case ACE_Event_Handler::READ_MASK: + case ACE_Event_Handler::ACCEPT_MASK: + result = buffer.eh_->handle_input (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::WRITE_MASK: + result = buffer.eh_->handle_output (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::EXCEPT_MASK: + result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE); + break; + default: + // Should we bail out if we get an invalid mask? + ACE_ERROR ((LM_ERROR, ASYS_TEXT ("invalid mask = %d\n"), buffer.mask_)); + } + if (result == -1) + buffer.eh_->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::EXCEPT_MASK); + } + + number_dispatched++; + + // Bail out if we've reached the <notify_threshold_>. Note that + // by default <notify_threshold_> is -1, so we'll loop until all + // the notifications in the pipe have been dispatched. + if (number_dispatched == this->select_reactor_->max_notify_iterations()) + break; + } + + // Reassign number_dispatched to -1 if things have gone seriously + // wrong. + if (n < 0) + number_dispatched = -1; + + + // Enqueue ourselves into the list of waiting threads. When we + // reacquire the token we'll be off and running again with ownership + // of the token. The postcondition of this call is that + // this->select_reactor_.token_.current_owner () == ACE_Thread::self (); + this->select_reactor_->renew(); + return number_dispatched; +} diff --git a/ace/CLASSIX/Select_Reactor.h b/ace/CLASSIX/Select_Reactor.h new file mode 100644 index 00000000000..54d45c687ca --- /dev/null +++ b/ace/CLASSIX/Select_Reactor.h @@ -0,0 +1,183 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Reactor.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_WRAPPER_CLASSIX_REACTOR_H +#define ACE_WRAPPER_CLASSIX_REACTOR_H + +/* ------------------------------------------------------------------------- */ +#include "ace/Select_Reactor.h" +#include "ace/Message_Block.h" +#include "CLASSIX/SAP.h" + + +class ACE_Export ACE_CLASSIX_Select_Reactor_Notify : + public ACE_Select_Reactor_Notify +{ + // = TITLE + // Unblock the <ACE_CLASSIX_Select_Reactor> from its event loop. + // + // = DESCRIPTION + // This replaces <ACE_Select_Reactor_Notify> class. + // Instead of using pipe, this class uses an Chorus IPC port to + // trigger the unblock event. + // +public: + // = Initialization and termination methods. + ACE_CLASSIX_Select_Reactor_Notify(void); + virtual int open (ACE_Select_Reactor *, int /* dusable_notify_pip */); + // Enables the notification port and register it with the reactor + virtual int close (void); + // Disables the notification port + + int dispatch_notifications (int &number_of_active_handles, + const ACE_Handle_Set &rd_mask); + // Handles pending threads (if any) that are waiting to unblock the + // Select_Reactor. + + ssize_t notify (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, + ACE_Time_Value * = 0); + // Called by a thread when it wants to unblock the Select_Reactor. + // This wakeups the <ACE_Select_Reactor> if currently blocked in + // select()/poll(). Pass over both the <Event_Handler> *and* the + // <mask> to allow the caller to dictate which <Event_Handler> + // method the <Select_Reactor> will invoke. The <ACE_Time_Value> + // indicates how long to blocking trying to notify the + // <Select_Reactor>. If <timeout> == 0, the caller will block until + // action is possible, else will wait until the relative time + // specified in *<timeout> elapses). + + virtual int handle_input (ACE_HANDLE handle); + // Called back by the Select_Reactor when a thread wants to unblock us. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_CLASSIX_Port_Core notification_port_; // CLASSIX' IPC port + ACE_CLASSIX_SAP notification_sap_; + // The HANDLE that the Select_Reactor is listening on and + // the HANDLE that threads wanting the attention of the + // Select_Reactor will write t are the same. + // It can be seen that the notification port is implicitly connected to the + // port from where the notification is written. In many cases, it will be + // the actor's default port. +}; + +class ACE_CLASSIX_Select_Reactor : public ACE_Select_Reactor + // = TITLE + // Implementing a Reactor for monitoring incoming data + // + // = DESCRIPTION + // This class redefines the wait_for_events() method of + // <ACE_Select_Reactor> class. + // + // The wait_for_events() method uses ipcReceive() to monitor + // all ENABLED ports for incoming messages. The ipcReceive() is + // set up such that it will find out the size of the message but will + // not read the message. The Chorus OS provides an ipcGetData() + // to read the message that has just been detected on the same + // thread. + // Once a message is detected on a particular + // port, the reactor will invoke the port handler's + // handle_input() method on the same thread. It is important that + // handle_input() shall immediately retrieve(use ipcGetData()) + // the message on the same + // thread and it shall not hold up this thread in the handle_input() + // routine for too long. This will allow the Reactor to respond to + // events more quickly. + // + // = NOTE + // Since chorus does not allow ipcReceive to monitor a subset of + // ENABLED ports. One cannot have two ACE_CLASSIX_Select_Reactors + // in one actor. + // +{ + public: + + + // = CURRENT MESSAGE + // The following message should be called in the handler's + // handle_input() routine. + // The handle_input() routine should not hold the reactor for too long. + virtual int get_current_info(ACE_HANDLE /* port */, + size_t& /* msg size */); + // Retruns the current messageage to the caleer if the supplied + // handle id is the same as the <current_handle_> + // Returns 0, if <msg size> constains the size of the message + // that the handler shall read. + // Returns -1, if the caller is not the expected handler. + + protected: + // = INITIALIZATION + ACE_CLASSIX_Select_Reactor (ACE_Timer_Queue * = 0); + // Initializes <ACE_CLASSIX_Select__Reactor> with the handler + // repository of the default size. + + ACE_CLASSIX_Select_Reactor (size_t size, + int restart = 0, + ACE_Timer_Queue * = 0); + // Initializes <ACE_CLASSIX_Select_Reactor> with the handler repository of + // size <size>. + + // multiplexer + virtual int wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &, + ACE_Time_Value *); + // Wait for events to occur. + + virtual int set_current_info_(ACE_HANDLE /* handle */, + size_t /* size of data */); + // record the handler and the size of the message that the handler shall + // read next. + + + // ACE_Recursive_Thread_Mutex lock_current_; + // lock for data relating to the current message. + // use token lock + + size_t current_msg_size_; + // size of the message that has just been detected. + + ACE_HANDLE current_handle_; + // handler id of the current address. + + friend class ACE_CLASSIX_Select_Reactor_Notify; + friend class ACE_CLASSIX_OS; + // for constructors + + private: + int handle_error_(int /* port handle */); + // Takes corrective action when errors occur. + int check_handles_(int /* port handle */); + // Makes sure the handler is valid. + + ACE_CLASSIX_Select_Reactor(ACE_CLASSIX_Select_Reactor const&); + ACE_CLASSIX_Select_Reactor const& operator=(ACE_CLASSIX_Select_Reactor const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Reactor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_WRAPPER_CLASSIX_REACTOR_H */ diff --git a/ace/CLASSIX/Stream.cpp b/ace/CLASSIX/Stream.cpp new file mode 100644 index 00000000000..886d81ac5d5 --- /dev/null +++ b/ace/CLASSIX/Stream.cpp @@ -0,0 +1,365 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// IPP +// +// = FILENAME +// CLASSIX/Stream.cpp +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#include "CLASSIX/Stream.h" + +#if !defined (__ACE_INLINE__) +#include "CLASSIX/Stream.i" +#endif /* __ACE_INLINE__ */ +/* ------------------------------------------------------------------------- */ +ACE_CLASSIX_Stream::ACE_CLASSIX_Stream(void) + : local_sap_ (), + local_sap_closed_ (0), + local_port_ (0), + peer_sap_ (), + peer_sap_closed_ (1) +// dest_site_ (-1) +{ +} + +ACE_CLASSIX_Stream::ACE_CLASSIX_Stream + (const ACE_CLASSIX_Port_Core& thePeer, + const ACE_CLASSIX_Port& theLocal) + : local_sap_ (theLocal), + local_sap_closed_ (0), + local_port_ (0), + peer_sap_ (thePeer), + peer_sap_closed_ (1) +// dest_site_ (-1) +{ + this->dest_.target = this->peer_sap_.get_addr()->get_id(); +} + +ACE_CLASSIX_Stream::ACE_CLASSIX_Stream(const ACE_CLASSIX_Port& thePeer, + const ACE_CLASSIX_Port& theLocal) + : local_sap_ (theLocal), + local_sap_closed_(0), + local_port_ (0), + peer_sap_ (thePeer), + peer_sap_closed_ (1) +// dest_site_ (-1) +{ + this->dest_.target = this->peer_sap_.get_addr()->get_id(); +} + + +ACE_CLASSIX_Stream::ACE_CLASSIX_Stream(const KnUniqueId& thePeer, + const ACE_CLASSIX_Port& theLocal) + : local_sap_ (theLocal), + local_sap_closed_(0), + local_port_ (0), + peer_sap_ (thePeer), + peer_sap_closed_ (1) +// dest_site_ (-1) +{ + this->dest_.target = this->peer_sap_.get_addr()->get_id(); +} + +int +ACE_CLASSIX_Stream::set_local_port(ACE_CLASSIX_Port_Core* thePort) +{ + delete this->local_port_; + if (this->local_sap_.open(thePort) == 0) + { + this->local_port_ = thePort; + return 0; + } + else + { + this->local_port_ = 0; + this->local_sap_.clear(); + return -1; + } +} + +int +ACE_CLASSIX_Stream::open(void) +{ + this->dest_.target = this->peer_sap_.get_addr()->get_id(); + this->open_writer(); + + if (!this->local_sap().is_configured() || + this->local_sap().get_handle() == + ACE_CLASSIX_DEFAULT_PORT::instance()->get_handle()) + { + delete this->local_port_; + ACE_NEW_RETURN(this->local_port_, ACE_CLASSIX_Port_Core(), -1); + return this->local_sap_.open(this->local_port_); + } + + return 0; +} + +int +ACE_CLASSIX_Stream::open(const ACE_Addr& theAddr) +{ + this->dest_.target = this->peer_sap_.get_addr()->get_id(); + this->open_writer(); + + if (!this->local_sap().is_configured() || + this->local_sap().get_handle() == + ACE_CLASSIX_DEFAULT_PORT::instance()->get_handle()) + { + delete this->local_port_; + if (theAddr.get_size() != this->local_sap().get_addr().get_size()) + return -1; + return this->local_sap_.open(theAddr); + } + return 0; +} + +int +ACE_CLASSIX_Stream::close_writer(void) +{ + if (this->peer_sap_closed_ == 0) + { + if (this->send_n(0, 0) < 0) + ACE_DEBUG((LM_DEBUG, "failed to send a zero byte msg\n")); + this->peer_sap_closed_ = 1; + } + return 0; +} + +void +ACE_CLASSIX_Stream::open_writer(void) +{ + this->peer_sap_closed_ = 0; +} + +int +ACE_CLASSIX_Stream::close(void) +{ + this->close_writer(); + + this->local_sap_.close(); + if (this->local_port_) + { + delete this->local_port_; + this->local_port_ = 0; + } + this->dest_.target = ACE_CLASSIX_OS::null_KnUniqueId(); + return 0; +} + +void +ACE_CLASSIX_Stream::set_target_() +{ + this->dest_.target = this->peer_sap_.get_addr()->get_id(); +} + +int +ACE_CLASSIX_Stream::set_peer_sap(const ACE_Addr& theAddr) +{ + if (this->peer_sap_.set(theAddr) == 0) + { + this->set_target_(); + return 0; + } + return -1; +} + +int +ACE_CLASSIX_Stream::set_peer_sap(const ACE_CLASSIX_Port_Core& theAddr) +{ + if (this->peer_sap_.set(theAddr) == 0) + { + this->set_target_(); + return 0; + } + return -1; +} + +int +ACE_CLASSIX_Stream::set_peer_sap(const KnUniqueId& theAddr) +{ + if (this->peer_sap_.set(theAddr) == 0) + { + this->set_target_(); + return 0; + } + return -1; +} + +int +ACE_CLASSIX_Stream::set_peer_sap(const KnCap& theAddr) +{ + if (this->peer_sap_.set(theAddr) == 0) + { + this->set_target_(); + return 0; + } + return -1; +} + +ssize_t +ACE_CLASSIX_Stream::send_n(const void* theBuf, size_t theLen, int theFlags) +{ + if (!this->is_writer_closed()) + { + this->set_mode_(theFlags); + return this->send_n(theBuf, theLen); + } + else + return 0; +} + +ssize_t +ACE_CLASSIX_Stream::send_n(const void* theBuf, size_t theLen) const +{ + if (!this->is_writer_closed()) + { + ACE_CLASSIX_Msg msg(theBuf, theLen); + int result = 0; + if ((result = ::ipcSend((KnMsgDesc*) msg.get(), + this->local_sap().get_handle(), + (KnIpcDest*) &this->dest_)) == 0) + return theLen; + else + { + errno = ACE_CLASSIX_OS::convert_io_error(result); + return -1; + } + } + else + { + return 0; + } +} + +ssize_t +ACE_CLASSIX_Stream::reply(const void* theBuf, size_t theLen) const +{ + if (!this->is_writer_closed()) + { + ACE_CLASSIX_Msg msg(theBuf, theLen); + if (int result = ::ipcReply((KnMsgDesc*) msg.get()) == 0) + return theLen; + else + { + errno = ACE_CLASSIX_OS::convert_io_error(result); + return -1; + } + } + else + return 0; +} + +ssize_t +ACE_CLASSIX_Stream::ipcRecv(void* theBuf, size_t theLen, + int theFlag, ACE_Time_Value* theTimeout) const +{ + if (!this->is_reader_closed()) + { + // In chorus environment, a negative value means block + // until recv is possible + int timeout = theTimeout == 0 ? -1 : theTimeout->msec(); + if (timeout == 0) + timeout = -1; + + if (theFlag & MSG_PEEK) + { + theBuf = 0; + theLen = 0; + } + + ACE_CLASSIX_Msg rmsg(theBuf, theLen); + int handle = this->local_sap().get_handle(); + int result = ::ipcReceive((KnMsgDesc*) rmsg.get(), &handle, + timeout); + if (result < 0) + { + errno = ACE_CLASSIX_OS::convert_io_error(result); + return -1; + } + else + return result; + } + else + { + errno = ENOTCONN; + return -1; + } +} + +ssize_t +ACE_CLASSIX_Stream::ipcRecv_n(void* theBuf, size_t theLen, + int theFlag, ACE_Time_Value* theTimeout) const +{ + // Timeout value applies to each around of receive. + // ....Should be adjusted after each round! + int len = 0; + void *next = theBuf; + size_t more = theLen; + for (int n = 0; + more > 0; + len += n, next += n, more -=n) + { + if ((n = this->ipcRecv(next, more, theFlag, theTimeout)) == -1) + break; + } + return len; +} + +ssize_t +ACE_CLASSIX_Stream::recv(void* theBuf, int theLen) const +{ + if (!this->is_reader_closed()) + { + ACE_CLASSIX_Msg rmsg(theBuf, theLen); + int result = ::ipcGetData(rmsg.get()); + if (result >= 0) + return result; + else if (result == K_EINVAL) + errno = EWOULDBLOCK; + else + errno = EFAULT; + + return -1; + } + else + return 0; +} + + + +void +ACE_CLASSIX_Stream::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, "ACE_CLASSIX_Stream...\n")); + ACE_DEBUG ((LM_DEBUG, "...local sap(%s)\n", + this->is_writer_closed() == 1 ? "closed" : "opened")); + if (this->local_port_) + ACE_DEBUG ((LM_DEBUG, "\towns the local port(%x)\n", + this->local_port_)); + this->local_sap().dump(); + + ACE_DEBUG ((LM_DEBUG, "...Peer sap(%s & %s)\n", + this->is_reader_closed() == 1 ? "closed" : "opened", + this->is_selectable() ? "enabled" : "disabled")); + this->peer_sap().dump(); + ACE_DEBUG((LM_DEBUG, "Dest- Target\n head = %x tail = %x\n", + this->dest_.target.uiHead, + this->dest_.target.uiTail + /* this->dest_site_ */)); + ACE_DEBUG((LM_DEBUG, "Dest- coTarget\n head = %x tail = %x\n", + this->dest_.coTarget.uiHead, + this->dest_.coTarget.uiTail + /* this->dest_site_ */)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/CLASSIX/Stream.h b/ace/CLASSIX/Stream.h new file mode 100644 index 00000000000..fb53ddc24fc --- /dev/null +++ b/ace/CLASSIX/Stream.h @@ -0,0 +1,268 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// CLASSIX/Stream.h +// +// = AUTHOR(S) +// Wei Chiang +// +// = COPYRIGHT +// Copyright 1998 Nokia Telecommunications +// +// ============================================================================ + +#ifndef ACE_CLASSIX_STREAM_H +#define ACE_CLASSIX_STREAM_H + +/* ------------------------------------------------------------------------- */ +#include <CLASSIX/SAP.h> +#include <CLASSIX/Peer_SAP.h> +#include <CLASSIX/Port_Default.h> + +class ACE_CLASSIX_Stream + // = TITLE + // Provides the stream interface for CLASSIX IPC communications. + // + // = DESCRIPTION + // This classes provides a stream wrapper over CLASSIX' + // IPC. It is designed to be an alternative to Stream type of + // communication in the UNIX AF_INET environment. + // + // To the user, the stream is connection-oriented. The stream + // is implemented on top of IPC, it is connectionless and its + // reliability is as good as what the raw IPC can offer. + // + // Since CLASSIX IPC is not intended to go across wide area network, + // it can be seen as an + // alternative to AF_INET's connection oriented stream, even though + // the CLASSIX IPC is connectionless. + // + // This class contains a local sap, peer sap and data holding + // delivery mode information. + // + // When a stream is created, the peer SAP information must be provided. + // The local SAP information may be provided in the constructor or + // open(). The local SAP information given in open() overrides the + // existing one. If the local SAP address is not given at all, it will + // allocate a port and use it as the local SAP. + // +{ + public: + ACE_CLASSIX_Stream(void); + // Default constructor, does not setup anything + ACE_CLASSIX_Stream(const ACE_CLASSIX_Port_Core&, /* remote port */ + const ACE_CLASSIX_Port& = + *ACE_CLASSIX_DEFAULT_PORT::instance()); /* local address */ + + ACE_CLASSIX_Stream(const ACE_CLASSIX_Port&, /* remote port address */ + const ACE_CLASSIX_Port& = + *ACE_CLASSIX_DEFAULT_PORT::instance());/* local address */ + + ACE_CLASSIX_Stream(const KnUniqueId&, /* remote port address */ + const ACE_CLASSIX_Port& = + *ACE_CLASSIX_DEFAULT_PORT::instance());/* local address */ + + // = IO + // Returns -1, if fault has occured during receive. errno contains + // the error condition. + // Returns no of bytes received/sent, otherwise. + // + virtual ssize_t send_n (const void *, /* buf */ + size_t, /* n */ + int /* flags */); + // Sends exactly n bytes (keep trying until n bytes are sent) + virtual ssize_t send_n (const void *, /* buf */ size_t /* n */) const; + // Sends n bytes(keep trying until n bytes are sent) + // Uses the current addressing mode + virtual ssize_t send (const void *, /* buf */ + size_t, /* n */ + int /* flags */); + // Sends n bytes. Same as send_n(buf, n, flag) + virtual ssize_t send (const void *, /* buf */ + size_t /* n */) const; + // Sends n bytes. same as send_n(buf, n). + virtual ssize_t reply (const void *, /* buf */ + size_t /* n */) const; + // Sends n bytes to the sender of the cureent thread's current message. + + ssize_t ipcRecv (void *, /* buffer */ + size_t, /* length */ + int = 0, /* flag: 0 or MSG_PEEK */ + ACE_Time_Value* = 0) const; /* timeout */ + // Recv an <n> byte buffer + // Wait up to <timeout> amount of time to receive up to <n> bytes + // into <buf> from <handle> (uses the <recv> call). If <recv> times + // out a -1 is returned with <errno == ETIMEOUT>. If it succeeds the + // number of bytes received is returned. + // If <timeout> == 0, the caller + // will block until action is possible, else will wait until the + // relative time specified in *<timeout> elapses). + ssize_t ipcRecv_n (void *, /* buffer */ + size_t, /* length */ + int = 0, /* flag: 0 or MSG_PEEK */ + ACE_Time_Value* = 0) const; /* timeout */ + // Continue until receives n bytes of data or an error has occurred. + // Retruns the no of bytes actually received. + // If it is less than expected, errno contains error info. + + ssize_t peek(ACE_Time_Value* = 0 /* timeout */) const; + // It is the same as recv(0, 0, MSG_PEEK, timeout) + // This must be followd by get_data() in order to read the peeked message + ssize_t recv(void* /*buf */, int /* len */) const; + // Gets data which have been peeked + ssize_t recv_n(void* /*buf */, int /* len */) const; + // Gets data which have been peeked + + // = ACCESS + virtual ACE_HANDLE get_handle (void) const; + // virtual void set_handle (ACE_HANDLE); + virtual void set_handle(ACE_HANDLE); + // set the local port's address according to the supplied handle + + const ACE_CLASSIX_SAP& local_sap(void) const; + // Returns read-only local sap + const ACE_CLASSIX_Peer_SAP& peer_sap(void) const; + // Returns read-only peer sap + int get_remote_addr (ACE_Addr & /* dest */) const; + // Returns 0, if the remote address has been setup, else -1. + // The <dest> parameter is not changed. + // This method is here for compatability with SOCK_Stream. + // Since the remote addr may be a port or a group and since the + // address formats are different between a port and a group, the caller + // cannot provide an appropriate buffer for recording the address. The + // <dest> parameter is therefore not used. + + + const ACE_CLASSIX_Port& local_addr(void) const; + // Returns local address in <ACE_CLASSIX_Port> format + + int is_selectable(void) const; + // Retruns 1, if the local SAP is enabled. + int is_writer_closed(void) const; + // Retruns 1, if writer side is closed. + int is_reader_closed(void) const; + // Retruns 1, if reader side is closed. + + + // = CONTROL + int set_peer_sap(const ACE_Addr&); + // Returns 0, if successful; returns -1, otherwise + // same as set_addr(const ACE_Addr&); + int set_peer_sap(const ACE_CLASSIX_Port_Core&); + // Returns 0, if successful; returns -1, otherwise + // same as void set_addr(const ACE_CLASSIX_Port_Core&); + int set_peer_sap (const KnUniqueId&); + // Returns 0, if successful; returns -1, otherwise + int set_peer_sap (const KnCap&); + // Returns 0, if successful; returns -1, otherwise + + virtual int enable(int) const; + virtual int disable(int) const; + // These two methods do nothing. They are here to maintain the same + // interface as other type of Stream class, e.g. ACE_SOCK_Stream + + int selectable(int = ACE_CLASSIX_SAP::DEFAULT_PRIORITY); + int unselectable(void); + // Enables/Disables the local port to be monitored (by a CLASSIX reactor) + // Default = DISABLED + virtual void open_writer(void); + virtual int close_writer(void); + // Closes down the writer + // Returns -1, if it fails; returns 0, otherwise + // Subclass can overwrite this with sophisticated mechanism, such as + // exchange protocol information with the peer. + virtual int close_reader(void); + // Closes down the writer + // Returns -1, if it fails; returns 0, otherwise + // Subclass can overwrite this with sophisticated mechanism, such as + // exchange protocol information with the peer. + + virtual int open(void); + // for local SAP... + // Creates a port and uses it as a SAP. + // A port can be created if the local_sap is not configured or + // it is configured and the local_sap uses the actor's default port. + // Returns -1, if it fails; returns 0, otherwise + virtual int open(const ACE_Addr&); + // for local SAP... + // Uses the supplied port information for the local SAP. + virtual int close(void); + // for local SAP... + // Deletes the optional local port and clears the local SAP infomration. + + // = OPTIONS + int control(u_int = K_BROADMODE); + int control(u_int, /* mode */ int /* site */ ); + // Interface for CLASSIX' send mode + + // = HELPER + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + protected: + friend class ACE_CLASSIX_CLD_Connector; + friend class ACE_CLASSIX_Connector; + friend class ACE_CLASSIX_Acceptor; + ACE_CLASSIX_SAP& get_local_sap(void); + // Returns local sap + ACE_CLASSIX_Peer_SAP& get_peer_sap(void); + // Returns peer sap + int set_local_port(ACE_CLASSIX_Port_Core*); + // Uses the supplied port as the local port and assumes the ownership + // of the port. The existing local port, if any, will be deleted. + // Returns 0, if it is successful. + // Returns -1, otherwise. The setting of the original local port + // will be erased. + + void set_target_(void); + // set the delivery target structure using the existing peer information + + virtual int set_mode_(u_int = K_BROADMODE); /* theMode */ + // Sets the addressing mode with the current setting of coTarget + virtual int set_mode_(u_int, /* mode */ int /* site */); + // Sets the addressing mode as well as the coTarget + + ACE_CLASSIX_SAP local_sap_; + int local_sap_closed_; + // 0 if it's not closed(default), + // 1 if it's closed. + ACE_CLASSIX_Port_Core *local_port_; + // if non-zero, it will be + // deleted on exit. + + ACE_CLASSIX_Peer_SAP peer_sap_; + int peer_sap_closed_; + // 0 if it's not closed(default), + // 1 if it's closed. + + // Mode applied destination address + // Can be changed by control()/set_mode_() + // Mode is applicable in IPC classes other than the Stream class. + // It is here since it is the destination format used by ipcSend. + + // with/without additional site information + // int dest_site_; + KnIpcDest dest_; + + private: + // Disable copy constructor + ACE_CLASSIX_Stream(ACE_CLASSIX_Stream const&); + ACE_CLASSIX_Stream const& operator=(ACE_CLASSIX_Stream const&); +}; + +/* ------------------------------------------------------------------------- */ + +#if defined (__ACE_INLINE__) +#include "CLASSIX/Stream.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_CLASSIX_CLDGRAM_H */ diff --git a/ace/CLASSIX/Stream.i b/ace/CLASSIX/Stream.i new file mode 100644 index 00000000000..a876a3d78c9 --- /dev/null +++ b/ace/CLASSIX/Stream.i @@ -0,0 +1,182 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_CLASSIX_Stream::~ACE_CLASSIX_Stream(void) +{ + this->close(); +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::control(u_int theMode) +{ + return this->set_mode_(theMode); +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::control(u_int theMode, int theSite) +{ + return this->set_mode_(theMode, theSite); +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::set_mode_(u_int theMode) +{ + return 0; +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::set_mode_(u_int theMode, int theSite) +{ + return 0; +} + +ACE_INLINE +ssize_t +ACE_CLASSIX_Stream::peek(ACE_Time_Value* theTimeout) const +{ + return this->ipcRecv(0, 0, MSG_PEEK, theTimeout); +} + +ACE_INLINE +ssize_t +ACE_CLASSIX_Stream::send(const void *theBuf, size_t theLen) const +{ + return this->send_n(theBuf, theLen); +} + +ACE_INLINE +ssize_t +ACE_CLASSIX_Stream::send(const void *theBuf,size_t theLen, int theFlag) +{ + return this->send_n(theBuf, theLen, theFlag); +} + +ACE_INLINE +ssize_t +ACE_CLASSIX_Stream::recv_n(void* theBuf, int theLen) const +{ + return this->recv_n(theBuf, theLen); +} + +ACE_INLINE +ACE_HANDLE +ACE_CLASSIX_Stream::get_handle(void) const +{ + return this->local_sap_.get_handle(); +} + +ACE_INLINE +void +ACE_CLASSIX_Stream::set_handle(ACE_HANDLE theHandle) +{ + this->local_sap_.set_handle(theHandle); +} + +ACE_INLINE +const ACE_CLASSIX_SAP& +ACE_CLASSIX_Stream::local_sap(void) const +{ + return this->local_sap_; +} + +ACE_INLINE +const ACE_CLASSIX_Peer_SAP& +ACE_CLASSIX_Stream::peer_sap(void) const +{ + return this->peer_sap_; +} + +ACE_INLINE +ACE_CLASSIX_SAP& +ACE_CLASSIX_Stream::get_local_sap(void) +{ + return this->local_sap_; +} + +ACE_INLINE +ACE_CLASSIX_Peer_SAP& +ACE_CLASSIX_Stream::get_peer_sap(void) +{ + return this->peer_sap_; +} + +ACE_INLINE +const ACE_CLASSIX_Port& +ACE_CLASSIX_Stream::local_addr(void) const +{ + return this->local_sap_.get_addr(); +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::selectable(int thePriority) +{ + return this->local_sap_.selectable(thePriority); +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::unselectable(void) +{ + return this->local_sap_.unselectable(); +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::is_selectable(void) const +{ + return this->local_sap_.is_selectable(); +} + + +ACE_INLINE +int +ACE_CLASSIX_Stream::is_writer_closed(void) const +{ + + return (this->peer_sap_closed_ == 1); +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::close_reader(void) +{ + this->local_sap_closed_ = 1; + return 0; +} + + +ACE_INLINE +int +ACE_CLASSIX_Stream::is_reader_closed(void) const +{ + + return this->local_sap_closed_ == 1; +} + + +ACE_INLINE +int +ACE_CLASSIX_Stream::enable(int) const +{ + return 0; +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::disable(int) const +{ + return 0; +} + +ACE_INLINE +int +ACE_CLASSIX_Stream::get_remote_addr(ACE_Addr&) const +{ + return this->peer_sap_closed_ == 0; +} |