summaryrefslogtreecommitdiff
path: root/tests/CLASSIX
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1998-06-18 04:13:58 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1998-06-18 04:13:58 +0000
commit70e1738416a17108b087ec4b4b35dd2ddb7ca49f (patch)
treeaa1234eb4c766900e6b0da717638b9d4a8e88af0 /tests/CLASSIX
parentdfdc610629ae7e8fd4839082737dbaad95da9847 (diff)
downloadATCD-70e1738416a17108b087ec4b4b35dd2ddb7ca49f.tar.gz
*** empty log message ***
Diffstat (limited to 'tests/CLASSIX')
-rw-r--r--tests/CLASSIX/Addr_Test.cpp115
-rw-r--r--tests/CLASSIX/CLD_Connector_Test.cpp391
-rw-r--r--tests/CLASSIX/Con_Acc_Test.cpp405
-rw-r--r--tests/CLASSIX/Con_Acc_Test.h77
-rw-r--r--tests/CLASSIX/Group_Test.cpp85
-rw-r--r--tests/CLASSIX/Notify_Test.cpp266
-rw-r--r--tests/CLASSIX/OS.cpp62
-rw-r--r--tests/CLASSIX/OS_Test.cpp43
-rw-r--r--tests/CLASSIX/README25
-rw-r--r--tests/CLASSIX/Reactor_Test.cpp150
-rw-r--r--tests/CLASSIX/Reactor_Test.h52
-rw-r--r--tests/CLASSIX/SOCK_Test.cpp99
-rw-r--r--tests/CLASSIX/Select_Reactor_Test.cpp166
-rw-r--r--tests/CLASSIX/Select_Reactor_Test.h51
-rw-r--r--tests/CLASSIX/Stream_Test.cpp110
-rw-r--r--tests/CLASSIX/test_config.h272
16 files changed, 2369 insertions, 0 deletions
diff --git a/tests/CLASSIX/Addr_Test.cpp b/tests/CLASSIX/Addr_Test.cpp
new file mode 100644
index 00000000000..03e35984363
--- /dev/null
+++ b/tests/CLASSIX/Addr_Test.cpp
@@ -0,0 +1,115 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// CLASSIX_Addr_Test.cpp
+//
+// = DESCRIPTION
+// This is a test of the <IPP_CLASSIX_Addr> class.
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#include "tests/test_config.h"
+#include "CLASSIX/Addr.h"
+#include "CLASSIX/SAP.h"
+#include "CLASSIX/Port_Default.h"
+
+class testSap : public ACE_CLASSIX_SAP
+{
+public:
+ testSap(): ACE_CLASSIX_SAP() {}
+ testSap(const ACE_Addr& theAddr) : ACE_CLASSIX_SAP(theAddr) {}
+
+ ~testSap() {ACE_DEBUG((LM_DEBUG, "~testSap()\n"));}
+};
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("Addr_Test");
+
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "------test virtual destructor------\n"));
+ testSap *n1 = new testSap();
+ ACE_CLASSIX_SAP *n2 = n1;
+ delete n2;
+
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "--------ACE_CLASSIX_Addr----------\n"));
+ ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n"));
+ ACE_CLASSIX_Port_Core *k2 = new ACE_CLASSIX_Port_Core();
+ int p2 = k2->get_handle();
+ ACE_CLASSIX_Port a2(*k2);
+ ACE_DEBUG((LM_INFO, "Addr a2(ipc port id = %d)\n", p2));
+ a2.dump();
+
+ ACE_CLASSIX_Port *a1 = ACE_CLASSIX_DEFAULT_PORT::instance();
+ ACE_DEBUG((LM_INFO, "Default port:"));
+ a1->dump();
+ a1->set_addr(a2.get_addr(), a2.get_size());
+ if (*a1 != *ACE_CLASSIX_DEFAULT_PORT::instance())
+ ACE_DEBUG((LM_ERROR, "???? Default port cannot be changed-2 !!!"));
+
+ ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n"));
+ ACE_CLASSIX_Port_Core k3;
+ ACE_CLASSIX_Port a3(k3);
+ ACE_DEBUG((LM_INFO, "Addr a3(ipc port id = %d)\n", k3.get_handle));
+ a3.dump();
+
+ ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n"));
+ ACE_CLASSIX_Port a4(a1->get_addr(), a1->get_size());
+ a4.dump();
+ if (a4 == *a1)
+ ACE_DEBUG((LM_INFO, "OK: Addr a4 == a1\n"));
+ else
+ ACE_ERROR((LM_ERROR, "Error: Addr a4 != a1\n"));
+
+ if (a4 != a2)
+ ACE_DEBUG((LM_INFO, "OK: Addr a4 != a2\n"));
+ else
+ ACE_ERROR((LM_ERROR, "Error: Addr a4 == a2\n"));
+
+ /* ================================================================== */
+
+ ACE_DEBUG((LM_INFO, "\n--------ACE_CLASSIX_Sap----------\n"));
+ testSap sap1;
+ sap1.set_addr(*a1);
+ ACE_CLASSIX_Port b1;
+ if (sap1.get_addr(b1) < 0)
+ ACE_ERROR((LM_ERROR, "failed to get sap1 address"));
+ if (b1 != *a1)
+ ACE_ERROR((LM_ERROR, "Error: sap1 address"));
+ sap1.dump();
+
+
+ ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n"));
+ testSap sap2(a2);
+ ACE_CLASSIX_Port b2;
+ if (sap2.get_addr(b2) < 0)
+ ACE_ERROR((LM_ERROR, "failed to get sap1 address"));
+ if (b2 != a2)
+ ACE_ERROR((LM_ERROR, "Error: sap2 address"));
+ b2.dump();
+ sap2.dump();
+
+
+ /* ================================================================== */
+ int result = 0;
+ int p = k2->get_handle();
+ delete k2;
+ if ((result = portDelete(K_MYACTOR, p)) == 0)
+ ACE_ERROR((LM_ERROR,
+ "????Error: delete already deleted port"));
+
+ ACE_END_TEST;
+ return 0;
+}
+
diff --git a/tests/CLASSIX/CLD_Connector_Test.cpp b/tests/CLASSIX/CLD_Connector_Test.cpp
new file mode 100644
index 00000000000..50caf31c7e1
--- /dev/null
+++ b/tests/CLASSIX/CLD_Connector_Test.cpp
@@ -0,0 +1,391 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// CLD_Connector.cpp
+//
+// = DESCRIPTION
+// Based on $ACE_ROOT/tests/MT_SOCK.cpp
+//
+// This is a multi-threaded torture test of the ACE_CLASSIX_CLD_Connector
+// class.
+//
+// The test spawns a server and multiple clients allowing clients to
+// exchange data with the server.
+//
+// This example demonstrates the following use cases
+// - server is a subclass of ACE_Svc_Handler,
+// but it does not involve an acceptor class.
+// - server multicasts message to the clients
+// - client uses ACE_CLASSIX_Connector to "connect" to the server
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/OS.h"
+#include "ace/Thread.h"
+#include "ace/Thread_Manager.h"
+#include "ace/Handle_Set.h"
+#include "ace/Svc_Handler.h"
+
+#include "CLASSIX/Reactor.h"
+#include "CLASSIX/Stream.h"
+#include "CLASSIX/Dgram_Mcast.h"
+#include "CLASSIX/Group_Stamp.h"
+#include "CLASSIX/CLD_Connector.h"
+
+#define MAX_TEST_CLIENTS 30
+#define TEST_STAMP 300
+#define ACE_CLASSIX_MCAST_DGRAM ACE_CLASSIX_Dgram_Mcast, ACE_CLASSIX_Group
+
+static ACE_Atomic_Op<ACE_Thread_Mutex, u_int> client_id = 0;
+
+
+struct client_arg
+{
+ ACE_Barrier *wait;
+ ACE_CLASSIX_Port_Core *server;
+};
+
+struct client_data
+{
+ u_int me;
+ char c;
+};
+
+class server_handler : public ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM,
+ ACE_MT_SYNCH>
+{
+public:
+ server_handler(int /* stamp */, const ACE_CLASSIX_Port_Core&);
+ // port that the server uses to receive data from all sorts of clients
+ virtual int open (void * = 0 /* args */);
+ virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
+ virtual int svc (void);
+
+ // = Demultiplexing hooks for Reactor
+ virtual int handle_input (ACE_HANDLE);
+ // The first int of each message identifies the sender
+
+private:
+ ACE_Atomic_Op<ACE_Thread_Mutex, u_int> in_svc_;
+ // 1 if svc() is running
+};
+
+server_handler::server_handler(int theStamp,
+ const ACE_CLASSIX_Port_Core & thePort)
+ : ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM, ACE_MT_SYNCH> (),
+ in_svc_ (0)
+{
+ if (this->peer().set_saps(theStamp, thePort) != 0)
+ ACE_DEBUG((LM_DEBUG, "failed to set up IO stream \n"));
+}
+
+int
+server_handler::open (void *)
+{
+ ACE_DEBUG((LM_DEBUG, "server_handler::open()\n"));
+ if (reactor ()->register_handler (this, READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%t)server_handler:: cannot register handler\n"),
+ -1);
+
+ if (this->peer().selectable() != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) failed to make Server's port %d selectable\n",
+ get_handle ()));
+ else
+ ACE_DEBUG ((LM_DEBUG, "(%t) created svc_handler for handle %d\n",
+ get_handle ()));
+
+ if (this->peer().control(K_BROADMODE) != 0)
+ ACE_DEBUG((LM_DEBUG, "(%t) %p\n"
+ "server cannot send data to destination\n"));
+
+ return this->activate (THR_BOUND);
+}
+
+int
+server_handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ while (this->in_svc_ == 1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%t) server is closing down\n"));
+
+ // Use a blank message to tell the thread to stop
+ ACE_Message_Block *mb = new ACE_Message_Block((size_t) 0);
+ ACE_Time_Value timeout(0, 10*1000); // wait for at most 10 usec
+ this->putq(mb, &timeout);
+ ACE_OS::thr_yield();
+ }
+
+ this->destroy();
+}
+
+int
+server_handler::handle_input(ACE_HANDLE)
+{
+ // Get input as fast as it can to free the reactor to handle other work.
+ size_t n = 0;
+ if (ACE_Reactor::instance()->
+ get_current_info(this->get_handle(),n) == -1)
+ ACE_ERROR_RETURN((LM_ERROR, "???(%t) failed to get input size\n"), -1);
+
+ ACE_Message_Block *msg;
+ ACE_NEW_RETURN(msg, ACE_Message_Block(n == 0 ? 1 : n), -1);
+ if (this->peer().recv(msg->wr_ptr(), n) == -1)
+ ACE_ERROR_RETURN((LM_ERROR, "???(%t) %p\n", "get_data()"), -1);
+ msg->wr_ptr(n);
+
+
+ if (this->putq(msg) == -1)
+ ACE_ERROR_RETURN((LM_ERROR, "???(%t) failed to enqueue message\n"),
+ -1);
+ return 0;
+}
+
+int
+server_handler::svc(void)
+{
+ this->peer().open_writer();
+ this->in_svc_ = 1;
+
+ ACE_Message_Block *mb = 0;
+ int result = 0;
+ char *storage[MAX_TEST_CLIENTS];
+
+ // initialize the expected result per client
+ for (int i = 0; i < MAX_TEST_CLIENTS; i++)
+ storage[i] = ACE_ALPHABET;
+
+ int len = sizeof (client_data);
+ int total_clients = MAX_TEST_CLIENTS;
+
+ ACE_DEBUG((LM_DEBUG, "(%t)server is waiting for clients\n"));
+ // read input
+ for (;;)
+ {
+ // wait until a message has arrived
+ result = this->getq (mb);
+
+ if (result == -1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "???(%t), error while waiting for a message "
+ "on the queue\n"), 0);
+ }
+
+ int length = mb->length ();
+
+ u_int client = 0;
+ if (length != 0 && length == len)
+ {
+ client = *((u_int*) mb->rd_ptr ());
+ mb->rd_ptr(sizeof (u_int));
+ char* data = storage[client];
+ // Check if the client has done
+ if (*(mb->rd_ptr()) == '\0')
+ {
+ ACE_DEBUG((LM_DEBUG, "handshake with client %d\n", client));
+ client_data response;
+ response.me = client;
+ int r = this->peer().send_n(&response, len);
+ if (r != len)
+ ACE_ERROR((LM_ERROR,
+ "(%t):%d %p\n",r,
+ "server faided to send handshake msg"));
+ total_clients--;
+ if (total_clients == 0)
+ {
+ mb->release();
+ ACE_DEBUG((LM_DEBUG, "(%t) end event loop \n"));
+ ACE_Reactor::end_event_loop();
+ this->in_svc_ = 0;
+ break;
+ }
+ }
+ if (*data != *(mb->rd_ptr()))
+ ACE_ERROR((LM_ERROR, "???(%t), invalid input\n"));
+ storage[client] = ++data;
+ }
+ else if (length > 0)
+ {
+ ACE_ERROR((LM_ERROR, "???(%t), invalid input length(%d)\n",
+ length));
+ }
+ mb->release();
+
+ }
+
+ return 0;
+}
+
+
+static void *
+client (void *arg)
+{
+ client_data info;
+ info.me = client_id++;
+ int info_len = sizeof (client_data);
+
+ client_arg *data = (client_arg*) arg;
+ ACE_CLASSIX_Port_Core *server_port = data->server;
+ ACE_CLASSIX_Port server_addr(*server_port);
+ ACE_Barrier *barrier = data->wait;
+ //===================================================================
+ // Stream & Connector
+ //
+// ACE_CLASSIX_Stream cli_stream(*server_port);
+ ACE_CLASSIX_Stream cli_stream;
+ // create a stream where the local SAP uses the actor's default port.
+
+ ACE_CLASSIX_CLD_Connector con;
+ // create a connector for the stream
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Connecting local and peer SAPs\n"));
+ // Connect local and peer SAPs.
+
+ barrier->wait();
+ //===================================================================
+ // Attempt a connect to the server...
+ // A local port will be created as a local SAP
+ if (con.connect (cli_stream, server_addr) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "connection failed"),
+ 0);
+ }
+ ACE_CLASSIX_Port client_addr;
+ if (cli_stream.local_sap().get_addr (client_addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "get_local_addr"), 0);
+ else
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected client at %d\n",
+ client_addr.get_handle ()));
+
+
+ //===================================================================
+ // Insert the local SAP to the test group
+ ACE_CLASSIX_Group_Stamp group(TEST_STAMP);
+ // group that the client's port is in
+ if (group.insert(&client_addr) == -1)
+ ACE_ERROR_RETURN((LM_ERROR,
+ "Failed to insert local SAP of client %d in to the"
+ "group \n"), -1);
+
+ //===================================================================
+ // Do not use Reactor, so disable local port from being monitored
+ int result = cli_stream.unselectable();
+ if (result != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) failed to disable local port(%d)\n",
+ result), -1);
+
+ //===================================================================
+ // Send data to server (correctly handles "incomplete writes").
+ char *c = ACE_ALPHABET;
+
+ do
+ {
+ ACE_OS::thr_yield();
+ info.c = *c;
+ if (cli_stream.send_n (&info, info_len) != info_len)
+ ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "send_n"));
+ }while(*c++ != '\0');
+
+ //===================================================================
+ // Close writer
+ // ACE_DEBUG ((LM_DEBUG, "(%P|%t) closing writer\n"));
+ // Explicitly close the writer-side of the connection.
+ //if (cli_stream.close_writer () == -1)
+ // ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close_writer"));
+
+ // Wait for handshake with server.
+ client_data response;
+ do
+ {
+ if (cli_stream.ipcRecv_n (&response, info_len) != info_len)
+ ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "recv_n"));
+ }
+ while (response.me != info.me);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) received handshake from server\n"));
+
+ // Close the connection completely.
+ if (cli_stream.close () == -1)
+ ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close"));
+
+ return 0;
+}
+
+
+static void
+spawn (ACE_CLASSIX_Port_Core* theServer)
+{
+ // create a port for the server
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting server at port %d\n",
+ theServer->get_handle ()));
+
+ // activate server
+ server_handler handler(TEST_STAMP, *theServer);
+ handler.open(); // make the server active
+
+ // activate clients
+ // make sure
+ // - we don't let client send messages before the event loop is running
+ ACE_Barrier wait(MAX_TEST_CLIENTS);
+ client_arg data;
+ data.server = theServer;
+ data.wait = &wait;
+
+ ACE_DEBUG ((LM_DEBUG, "(%t) starting clients\n"));
+ if (ACE_Thread_Manager::instance ()->spawn_n
+ (MAX_TEST_CLIENTS,
+ ACE_THR_FUNC (client),
+ (void *) &data,
+ THR_BOUND | THR_DETACHED) == -1)
+ ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "spawn failed"));
+
+ // handle event
+ ACE_DEBUG((LM_DEBUG, "(%t)run event loop\n"));
+ ACE_Reactor::run_event_loop();
+
+ // wait until all server has completed
+ ACE_Thread_Manager::instance()->wait_task(&handler);
+}
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("CLD_Connector_Test");
+
+ // initialize classix environment, such as reactor
+ ACE_CLASSIX_OS classix;
+
+ // running server and clients
+ ACE_CLASSIX_Port_Core server_port;
+ spawn(&server_port);
+
+
+ // Wait all the threads to exit.
+ ACE_Thread_Manager::instance ()->wait ();
+
+ ACE_END_TEST;
+ return 0;
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Atomic_Op<ACE_Thread_Mutex, u_int>;
+template class ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM, ACE_MT_SYNCH>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, u_int>
+#pragma instantiate ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM, ACE_MT_SYNCH>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+
diff --git a/tests/CLASSIX/Con_Acc_Test.cpp b/tests/CLASSIX/Con_Acc_Test.cpp
new file mode 100644
index 00000000000..7c0a896eb10
--- /dev/null
+++ b/tests/CLASSIX/Con_Acc_Test.cpp
@@ -0,0 +1,405 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Con_Acc__Test.cpp
+//
+// = DESCRIPTION
+// Based on $ACE_ROOT/tests/Priority_Reactor_Test.cpp
+//
+// This is a test of the <ACE_Priority_Reactor>. The test forks
+// two processes (for a total of three processes) which connect to
+// the main process and The clients send data to a connector,
+// interestingly enough the acceptor will give more priority to
+// the second connection, which should run always before the first
+// one.
+//
+// The test itself is interesting, it shows how to write very
+// simple <ACE_Svc_Handler>, <ACE_Connectors> and <ACE_Acceptors>.
+//
+// = AUTHOR
+// Carlos O'Ryan
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/Get_Opt.h"
+#include "ace/Acceptor.h"
+#include "ace/Handle_Set.h"
+#include "ace/Connector.h"
+#include "ace/Strategies.h"
+#include "ace/Auto_Ptr.h"
+#include "ace/Priority_Reactor.h"
+
+#include "CLASSIX/Connector.h"
+#include "CLASSIX/Acceptor.h"
+#include "Con_Acc_Test.h"
+
+
+// The number of children to run, it can be changed using the -c
+// option.
+static int opt_nchildren = 2 /* 10 */;
+
+// The number of loops per children, it can be changed using the -l
+// option.
+static int opt_nloops = 200 /* 200 */;
+
+// If not set use the normal reactor, it can be changed using the -d
+// option.
+static int opt_priority_reactor = 1;
+
+// Maximum time to wait for the test termination (-t)
+static int opt_max_duration = 60;
+
+// Maximum number of retries to connect, it can be changed using the
+// -m option.
+static int max_retries = 5;
+
+typedef ACE_Connector<Write_Handler, ACE_CLASSIX_CONNECTOR>
+ CONNECTOR;
+typedef ACE_Acceptor<Read_Handler, ACE_CLASSIX_ACCEPTOR>
+ ACCEPTOR;
+
+typedef ACE_CLASSIX_Port ADDR;
+
+ACE_Atomic_Op<ACE_Thread_Mutex, int> Read_Handler::waiting_ = 0;
+ACE_Atomic_Op<ACE_Thread_Mutex, int> Read_Handler::started_ = 0;
+
+void
+Read_Handler::set_countdown (int nchildren)
+{
+ Read_Handler::waiting_ = nchildren;
+}
+
+int
+Read_Handler::get_countdown (void)
+{
+ return Read_Handler::waiting_.value();
+}
+
+int
+Read_Handler::open (void *)
+{
+ if (this->peer ().enable (ACE_NONBLOCK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Read_Handler::open, "
+ "cannot set non blocking mode"), -1);
+
+ if (reactor ()->register_handler (this, READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Read_Handler::open, "
+ "cannot register handler"), -1);
+
+ // A number larger than the actual number of priorities, so some
+ // clients are misbehaved, hence pusnished.
+ const int max_priority = 15;
+
+ this->priority (ACE_Event_Handler::LO_PRIORITY + started_.value() % max_priority);
+ started_++;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) created svc_handler for handle %d "
+ "with priority %d\n",
+ get_handle (),
+ priority ()));
+ return 0;
+}
+
+int
+Read_Handler::handle_input (ACE_HANDLE h)
+{
+ char buf[BUFSIZ];
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t|%x) read from handle %d...", this, h));
+ ssize_t result = this->peer ().recv (buf, sizeof (buf));
+
+ if (result <= 0)
+ {
+ if (result < 0 && errno == EWOULDBLOCK)
+ return 0;
+
+ if (result != 0)
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) %p\n",
+ "Read_Handler::handle_input"));
+ waiting_--;
+
+ if (waiting_ == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Last svc_handler closed, shutting down\n"));
+ ACE_Reactor::instance()->end_event_loop();
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) Read_Handler(%d)::handle_input closing down\n", h));
+ return -1;
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "...(%P|%t) read %d bytes from handle %d, priority %d\n",
+ result, h, priority ()));
+ return 0;
+}
+
+int
+Write_Handler::open (void *)
+{
+ return 0;
+}
+
+int
+Write_Handler::svc (void)
+{
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) in svc\n"));
+ // Send several short messages, doing pauses between each message.
+ // The number of messages can be controlled from the command line.
+
+ ACE_Time_Value pause (0, 1000);
+ for (int i = 0; i < opt_nloops; ++i)
+ {
+ if (this->peer ().send_n (ACE_ALPHABET,
+ sizeof (ACE_ALPHABET) - 1) == -1)
+ {
+ ACE_DEBUG((LM_DEBUG, "%t %p\n", "send_n\n"));
+ ACE_OS::sleep (pause);
+ }
+ }
+ this->peer().close_writer();
+ return 0;
+}
+
+// Execute the client tests.
+static void *
+client (void *arg)
+{
+ ADDR *connection_addr = (ADDR *) arg;
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) running client\n"));
+ CONNECTOR connector;
+
+ Write_Handler *writer = 0;
+
+ // Do exponential backoff connections
+ ACE_Synch_Options options = ACE_Synch_Options::synch;
+
+ // Start with one msec timeouts.
+ ACE_Time_Value msec (0, 1000);
+ options.timeout (msec);
+
+ // Try up to <max_retries> to connect to the server.
+ for (int i = 0; i < max_retries; i++)
+ {
+ if (connector.connect (writer,
+ *connection_addr,
+ options) == -1)
+ {
+ // Double the timeout...
+ ACE_Time_Value tmp = options.timeout ();
+ tmp += options.timeout ();
+ options.timeout (tmp);
+ writer = 0;
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) still trying to connect\n"));
+ }
+ else
+ {
+ // Let the new Svc_Handler to its job...
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) running svc\n"));
+ writer->svc ();
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) finishing client\n"));
+
+ // then close the connection and release the Svc_Handler.
+ writer->destroy ();
+
+ return 0;
+ }
+ }
+
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) failed to connect after %d retries\n",
+ max_retries));
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ACE_START_TEST ("Con_Acc_Test");
+
+ // initialize environment, eg. reactor, etc.
+ ACE_CLASSIX_OS os;
+
+ ACE_Get_Opt getopt (argc, argv, "dc:l:m:t:", 1);
+
+ for (int c; (c = getopt ()) != -1; )
+ switch (c)
+ {
+ case 'd':
+ opt_priority_reactor = 0;
+ break;
+ case 'c':
+ opt_nchildren = atoi (getopt.optarg);
+ break;
+ case 'l':
+ opt_nloops = atoi (getopt.optarg);
+ break;
+ case 'm':
+ max_retries = atoi (getopt.optarg);
+ break;
+ case 't':
+ opt_max_duration = atoi (getopt.optarg);
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR, "Usage: Priority_Reactor_Test "
+ " [-d] (disable priority reactor)\n"
+ " [-c nchildren] (number of threads/processes)\n"
+ " [-l loops] (number of loops per child)\n"
+ " [-m maxretries] (attempts to connect)\n"
+ " [-t max_time] (limits test duration)\n"), -1);
+ ACE_NOTREACHED (break);
+ }
+#if 0
+ // Manage memory automagically.
+ // Note: This ordering is very subtle...
+ auto_ptr<ACE_Reactor> reactor;
+ auto_ptr<ACE_Select_Reactor> impl;
+
+ if (opt_priority_reactor)
+ {
+ ACE_Select_Reactor *impl_ptr;
+ ACE_NEW_RETURN (impl_ptr, ACE_Priority_Reactor, -1);
+ impl = auto_ptr<ACE_Select_Reactor> (impl_ptr);
+ ACE_Reactor *reactor_ptr;
+ ACE_NEW_RETURN (reactor_ptr, ACE_Reactor (impl_ptr), -1);
+ reactor = auto_ptr<ACE_Reactor> (reactor_ptr);
+ ACE_Reactor::instance (reactor_ptr);
+ }
+#endif
+
+ Read_Handler::set_countdown (opt_nchildren);
+
+ // Acceptor
+ ACE_DEBUG((LM_DEBUG, "Create an Acceptor\n"));
+ ACCEPTOR acceptor(ACE_Reactor::instance(), 0);
+ // The acceptor uses the global reactor and does not use select.
+
+ acceptor.priority (ACE_Event_Handler::HI_PRIORITY);
+ ADDR server_addr;
+
+ // Bind acceptor to any port and then find out what the port was.
+ ACE_DEBUG((LM_DEBUG, "Open the acceptor\n"));
+ if (acceptor.open ((const ADDR &) ACE_Addr::sap_any) == -1
+ || acceptor.acceptor ().get_local_addr (server_addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "open"), -1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) starting server at port %d\n",
+ server_addr.get_port_number ()));
+
+ ADDR connection_addr (server_addr);
+
+ int i;
+
+#if defined (ACE_HAS_THREADS)
+ for (i = 0; i < opt_nchildren; ++i)
+ {
+ if (ACE_Thread_Manager::instance ()->spawn
+ (ACE_THR_FUNC (client),
+ (void *) &connection_addr,
+ THR_NEW_LWP | THR_DETACHED) == -1)
+ ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "thread create failed"));
+ }
+#elif !defined (ACE_LACKS_FORK)
+ for (i = 0; i < opt_nchildren; ++i)
+ {
+ switch (ACE_OS::fork ("child"))
+ {
+ case -1:
+ ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "fork failed"));
+ exit (-1);
+ /* NOTREACHED */
+ case 0:
+ client (&connection_addr);
+ exit (0);
+ break;
+ /* NOTREACHED */
+ default:
+ break;
+ /* NOTREACHED */
+ }
+ }
+#else
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) only one thread may be run in a process on this platform\n%a", 1));
+#endif /* ACE_HAS_THREADS */
+
+ ACE_Time_Value tv (opt_max_duration);
+
+ ACE_Reactor::instance()->register_handler
+ (&acceptor, ACE_Event_Handler::READ_MASK);
+ ACE_Reactor::instance()->run_event_loop (tv);
+
+ if (Read_Handler::get_countdown () != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) running out of time, "
+ "probably due to failed connections.\n"));
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) waiting for the children...\n"));
+
+#if defined (ACE_HAS_THREADS)
+ ACE_Thread_Manager::instance ()->wait ();
+#elif !defined (ACE_WIN32) && !defined (VXWORKS) && !defined (ACE_PSOS)
+ for (i = 0; i < opt_nchildren; ++i)
+ {
+ pid_t pid = ACE_OS::wait();
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) child %d terminated\n", pid));
+ }
+#else
+ /* NOTREACHED */
+ // We aborted on the previous #ifdef
+#endif /* ACE_HAS_THREADS */
+
+ ACE_END_TEST;
+ return 0;
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Connector<Write_Handler, ACE_CLASSIX_CONNECTOR>;
+template class ACE_Acceptor<Read_Handler, ACE_CLASSIX_ACCEPTOR>;
+template class ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH>;
+template class auto_ptr<ACE_Reactor>;
+template class ACE_Auto_Basic_Ptr<ACE_Reactor>;
+template class auto_ptr<ACE_Select_Reactor>;
+template class ACE_Auto_Basic_Ptr<ACE_Select_Reactor>;
+template class ACE_Map_Manager<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>;
+template class ACE_Map_Iterator_Base<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>;
+template class ACE_Map_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>;
+template class ACE_Map_Reverse_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>;
+template class ACE_Map_Entry<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*>;
+template class ACE_Svc_Tuple<Write_Handler>;
+template class ACE_Atomic_Op<ACE_Thread_Mutex, int>;
+
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Connector<Write_Handler, ACE_CLASSIX_CONNECTOR>
+#pragma instantiate ACE_Acceptor<Read_Handler, ACE_CLASSIX_ACCEPTOR>
+#pragma instantiate ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH>
+#pragma instantiate auto_ptr<ACE_Reactor>
+#pragma instantiate ACE_Auto_Basic_Ptr<ACE_Reactor>
+#pragma instantiate auto_ptr<ACE_Select_Reactor>
+#pragma instantiate ACE_Auto_Basic_Ptr<ACE_Select_Reactor>
+#pragma instantiate ACE_Map_Manager<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Reverse_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Entry<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*>
+#pragma instantiate ACE_Svc_Tuple<Write_Handler>
+#pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, int>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/tests/CLASSIX/Con_Acc_Test.h b/tests/CLASSIX/Con_Acc_Test.h
new file mode 100644
index 00000000000..290eb4c5f34
--- /dev/null
+++ b/tests/CLASSIX/Con_Acc_Test.h
@@ -0,0 +1,77 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Priority_Reactor_Test.h
+//
+// = DESCRIPTION
+// This class gets its own header file to work around AIX C++
+// compiler "features" related to template instantiation... It is
+// only used by Priority_Reactor_Test.cpp.
+//
+// = AUTHOR
+// Carlos O'Ryan
+//
+// ============================================================================
+
+#ifndef ACE_TESTS_PRIORITY_REACTOR_TEST_H
+#define ACE_TESTS_PRIORITY_REACTOR_TEST_H
+
+#include "ace/Service_Config.h"
+#include "ace/SOCK_Stream.h"
+#include "ace/Svc_Handler.h"
+#include "ace/Synch_T.h"
+
+#define ACE_CLASSIX_STREAM ACE_CLASSIX_Stream, ACE_CLASSIX_Addr
+#define ACE_CLASSIX_CONNECTOR ACE_CLASSIX_Connector, ACE_CLASSIX_Port
+#define ACE_CLASSIX_ACCEPTOR ACE_CLASSIX_Acceptor, ACE_CLASSIX_Port
+
+class Read_Handler : public ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH>
+ // = TITLE
+ // A Svc_Handler with a priority twist.
+ //
+ // = DESCRIPTION
+ // This Svc_Handler receives the data sent by the childs or writer
+ // threads; each one sets it own priority to a new level, in a
+ // cyclic manner. The main point is test and exercise the
+ // priority dispatching features of ACE_Priority_Reactor.
+{
+public:
+ static void set_countdown (int nchildren);
+ // Set the number of children or writer threads we will be running,
+ // when they are all gone we terminate the reactor loop.
+
+ static int get_countdown (void);
+ // Get the number of children we are still waiting for.
+
+ virtual int open (void *);
+ virtual int handle_input (ACE_HANDLE h);
+ // The Svc_Handler callbacks.
+
+private:
+ static ACE_Atomic_Op<ACE_Thread_Mutex, int> waiting_;
+ // How many writers are we waiting for.
+
+ static ACE_Atomic_Op<ACE_Thread_Mutex, int> started_;
+ // How many readers have started.
+};
+
+class Write_Handler : public ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH>
+ // = TITLE
+ // A simple writer.
+ //
+ // = DESCRIPTION
+ // This Svc_Handler simply connects to a server and sends some
+ // output to it. Its purpose is to feed the test.
+{
+public:
+ virtual int open (void *);
+ virtual int svc (void);
+};
+
+#endif /* ACE_TESTS_PRIORITY_REACTOR_TEST_H */
diff --git a/tests/CLASSIX/Group_Test.cpp b/tests/CLASSIX/Group_Test.cpp
new file mode 100644
index 00000000000..73ba648d4a3
--- /dev/null
+++ b/tests/CLASSIX/Group_Test.cpp
@@ -0,0 +1,85 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Group_Test.cpp
+//
+// = DESCRIPTION
+// This is a test of the <IPP_CLASSIX_Group_*> class.
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#include "tests/test_config.h"
+#include "CLASSIX/Addr.h"
+#include "CLASSIX/Group_Stamp.h"
+#include "CLASSIX/Group_Dynamic.h"
+
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("Group_Test");
+
+ int stamp = 20;
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "-----------group target-----------\n"));
+
+ ACE_DEBUG((LM_INFO, "constrctor(Stamp)..................\n"));
+ ACE_CLASSIX_Group_Stamp t0(100);
+ t0.dump();
+
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "-----------group target-----------\n"));
+
+ ACE_DEBUG((LM_INFO, "constrctor(Stamp)..................\n"));
+ ACE_CLASSIX_Group_Stamp t1(stamp);
+ t1.dump();
+
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "empty constrctor(Stamp) & set_group()\n"));
+ ACE_CLASSIX_Group_Stamp t2;
+ if (t2 == t1)
+ ACE_DEBUG((LM_ERROR, "t2 == t1, should be !=\n"));
+ t2.set_addr(&stamp);
+ t2.dump();
+ if (t2 != t1)
+ ACE_DEBUG((LM_ERROR, "????t2 != t1, should be ==\n"));
+
+
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "Constrctor(Dynamic) & set_group()\n"));
+ ACE_CLASSIX_Group_Dynamic t3;
+ t3.dump();
+
+ ACE_CLASSIX_Group_Stamp t4;
+ t4.set_addr(t2.get_addr(), t2.get_size());
+ t4.dump();
+ if (t4 == t2)
+ ACE_DEBUG((LM_ERROR, "????t4 == t2, should be !=\n"));
+ t4.set_addr(&stamp);
+ t4.dump();
+ if (t4 != t2)
+ ACE_DEBUG((LM_ERROR, "????t4 != t2, should be ==\n"));
+
+ ACE_CLASSIX_Group t5(t3.get_addr(), t3.get_size());
+ t5.dump();
+ if (t5 != t3)
+ ACE_DEBUG((LM_ERROR, "????t5 != t3, should be ==\n"));
+
+
+ if (t2 != t1)
+ ACE_DEBUG((LM_ERROR, "????t2 != t1, should be ==\n"));
+
+ /* ================================================================== */
+ ACE_END_TEST;
+ return 0;
+}
+
diff --git a/tests/CLASSIX/Notify_Test.cpp b/tests/CLASSIX/Notify_Test.cpp
new file mode 100644
index 00000000000..5db9285e256
--- /dev/null
+++ b/tests/CLASSIX/Notify_Test.cpp
@@ -0,0 +1,266 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Notify_Test.cpp
+//
+// = DESCRIPTION
+// Based on $ACE_ROOT/tests/Reactors_test.cpp
+//
+// This is a test that performs a torture test of multiple
+// <ACE_Reactors> and <ACE_Tasks> in the same process.
+//
+// = NOTE
+// Use ACE_Reactor and thus Chorus's socket sub-system, it behave
+// quite stragnely including a printout such as
+// "(15) task_9: !!!notify: Not a stream device"
+//
+// = AUTHOR
+// Prashant Jain, Detlef Becker, and Douglas C. Schmidt
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/Synch.h"
+#include "ace/Task.h"
+
+#include "CLASSIX/OS.h"
+#include "CLASSIX/Reactor.h"
+
+#if defined (ACE_HAS_THREADS)
+
+ACE_Thread_Manager *tm;
+
+static const int MAX_TASKS = 20;
+
+class Test_Task : public ACE_Task<ACE_MT_SYNCH>
+ // = TITLE
+ // Exercise the tasks.
+{
+public:
+ // = Initialization and termination methods.
+ Test_Task (void);
+ ~Test_Task (void);
+
+ // = Task hooks.
+ virtual int open (void *args = 0);
+ virtual int close (u_long flags = 0);
+ virtual int svc (void);
+
+ // = Event Handler hooks.
+ virtual int handle_input (ACE_HANDLE handle);
+ virtual int handle_close (ACE_HANDLE fd,
+ ACE_Reactor_Mask close_mask);
+
+private:
+ size_t handled_;
+ char name_[10];
+ // Number of iterations handled.
+
+ static int task_count_;
+ // Number of tasks running.
+};
+
+// Static data member initialization.
+int Test_Task::task_count_ = 0;
+
+static ACE_Atomic_Op<ACE_Thread_Mutex, int> done_count = MAX_TASKS * 2;
+
+static ACE_Recursive_Thread_Mutex recursive_lock;
+
+Test_Task::Test_Task (void)
+ : handled_ (0)
+{
+ ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock);
+
+ Test_Task::task_count_++;
+
+ ACE_OS::sprintf(this->name_, "%s_%d", "task", Test_Task::task_count_);
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) TT+ %s\n",
+ this->name_));
+}
+
+Test_Task::~Test_Task (void)
+{
+ ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) TT- %s: %d\n",
+ this->name_, Test_Task::task_count_));
+
+ ACE_ASSERT (Test_Task::task_count_ == 0);
+}
+
+int
+Test_Task::open (void *args)
+{
+ this->reactor ((ACE_Reactor *) args);
+ return this->activate (THR_NEW_LWP);
+}
+
+int
+Test_Task::close (u_long)
+{
+ ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock, -1);
+
+ Test_Task::task_count_--;
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) close %s, task_count_ = %d\n",
+ this->name_, Test_Task::task_count_));
+
+ if (Test_Task::task_count_ < 0)
+ abort ();
+
+ return 0;
+}
+
+int
+Test_Task::svc (void)
+{
+ ACE_DEBUG ((LM_DEBUG, "(%t) svc(%s)\n", this->name_));
+
+ for (size_t i = 0; i < ACE_MAX_ITERATIONS; i++)
+ {
+ ACE_OS::thr_yield ();
+
+ // Only wait up to 10 milliseconds to notify the Reactor.
+ ACE_Time_Value timeout (0, 10 * 1000);
+
+ if (this->reactor ()->notify (this,
+ ACE_Event_Handler::READ_MASK,
+ &timeout) == -1)
+ {
+ if (errno == ETIME)
+ ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", "notify() timed out"));
+ else
+ ACE_ERROR_RETURN ((LM_ERROR, "(%t) %s: %p\n", this->name_,
+ "!!!notify"), -1);
+ }
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "(%t) end svc(%s)\n", this->name_));
+ return 0;
+}
+
+int
+Test_Task::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ return 0;
+}
+
+int
+Test_Task::handle_input (ACE_HANDLE)
+{
+ this->handled_++;
+
+ if (this->handled_ == ACE_MAX_ITERATIONS)
+ {
+ done_count--;
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) handle_input, handled_ = %d, done_count = %d\n",
+ this->handled_, done_count.value ()));
+ }
+
+ ACE_OS::thr_yield ();
+ return -1; // this will trigger hnalde_close() be called
+}
+
+static void *
+worker (void *args)
+{
+ ACE_DEBUG((LM_DEBUG, "(%t) worker started\n"));
+ ACE_Reactor *reactor = (ACE_Reactor *) args;
+
+ // Make this thread the owner of the Reactor's event loop.
+ reactor->owner (ACE_Thread::self ());
+
+ // Use a timeout to inform the Reactor when to shutdown.
+ ACE_Time_Value timeout (1);
+
+ for (;;)
+ {
+ switch (reactor->handle_events (timeout))
+ {
+ case -1:
+ ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "reactor"), 0);
+ /* NOTREACHED */
+ case 0:
+ ACE_ERROR_RETURN ((LM_ERROR, "(%t) Reactor shutdown\n"), 0);
+ /* NOTREACHED */
+ default:
+ timeout.sec(1);
+ }
+ }
+
+ ACE_NOTREACHED (return 0);
+}
+
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Atomic_Op<ACE_Thread_Mutex, int>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, int>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+#endif /* ACE_HAS_THREADS */
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("Notify_Test");
+
+ // initialize the singletons and environment
+ ACE_CLASSIX_OS classix;
+
+#if defined (ACE_HAS_THREADS)
+ ACE_ASSERT (ACE_LOG_MSG->op_status () != -1);
+
+ tm = ACE_Thread_Manager::instance ();
+
+ ACE_Reactor reactor;
+ ACE_ASSERT (ACE_LOG_MSG->op_status () != -1);
+
+ Test_Task tt1[MAX_TASKS];
+ Test_Task tt2[MAX_TASKS];
+
+ // Activate all of the Tasks.
+
+ for (int i = 0; i < MAX_TASKS; i++)
+ {
+ tt1[i].open (ACE_Reactor::instance ());
+// tt2[i].open (&reactor);
+ tt2[i].open (ACE_Reactor::instance ());
+ }
+
+ // Spawn two threads each running a different reactor.
+
+ if (ACE_Thread_Manager::instance ()->spawn
+ (ACE_THR_FUNC (worker),
+ (void *) ACE_Reactor::instance (),
+ THR_BOUND | THR_DETACHED) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1);
+
+#if 0
+ else if (ACE_Thread_Manager::instance ()->spawn
+ (ACE_THR_FUNC (worker), (void *) &reactor,
+ THR_BOUND | THR_DETACHED) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1);
+#endif
+
+ if (ACE_Thread_Manager::instance ()->wait () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "wait"), -1);
+
+ ACE_DEBUG ((LM_DEBUG, "(%t) all threads are finished \n"));
+
+#else
+ ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n"));
+#endif /* ACE_HAS_THREADS */
+ ACE_END_TEST;
+ return 0;
+}
diff --git a/tests/CLASSIX/OS.cpp b/tests/CLASSIX/OS.cpp
new file mode 100644
index 00000000000..7327d4aae69
--- /dev/null
+++ b/tests/CLASSIX/OS.cpp
@@ -0,0 +1,62 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// CLASSIX_SOCK_Test.cpp
+//
+// = DESCRIPTION
+// This is a test of the <IPP_CLASSIX_Addr> class.
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#include "tests/test_config.h"
+#include "wrapper/CLASSIX_Addr.h"
+
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("SOCK_Test");
+
+ IPP_CLASSIX_Addr a1;
+ ACE_DEBUG((LM_INFO, "Addr a1:"));
+ a1.dump();
+
+ KnUniqueId k2;
+ ::portCreate(K_MYACTOR, &k2);
+ int p2 = ::portLi(&k2);
+ IPP_CLASSIX_Addr a2(k2);
+ ACE_DEBUG((LM_INFO, "Addr a2(ipc port id = %d)\n", p2));
+ a2.dump();
+
+ KnUniqueId k3;
+ ::portCreate(K_MYACTOR, &k3);
+ int p3 = ::portLi(&k3);
+ IPP_CLASSIX_Addr a3(p3);
+ ACE_DEBUG((LM_INFO, "Addr a3(ipc port id = %d)\n", p3));
+ a3.dump();
+
+ IPP_CLASSIX_Addr a4(a1);
+ if (a4 == a1)
+ ACE_DEBUG((LM_INFO, "OK: Addr a4 == a1\n"));
+ else
+ ACE_ERROR((LM_ERROR, "Error: Addr a4 != a1\n"));
+
+ if (a4 != a2)
+ ACE_DEBUG((LM_INFO, "OK: Addr a4 != a2\n"));
+ else
+ ACE_ERROR((LM_ERROR, "Error: Addr a4 == a2\n"));
+
+
+ ACE_END_TEST;
+ return 0;
+}
+
diff --git a/tests/CLASSIX/OS_Test.cpp b/tests/CLASSIX/OS_Test.cpp
new file mode 100644
index 00000000000..4af32e781f0
--- /dev/null
+++ b/tests/CLASSIX/OS_Test.cpp
@@ -0,0 +1,43 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// CLASSIX_OS_Test.cpp
+//
+// = DESCRIPTION
+// This is a test of the <ACE_CLASSIX_OS> class.
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#include "tests/test_config.h"
+#include "CLASSIX/OS.h"
+
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("CLASSIX_OS_Test");
+
+ ACE_DEBUG((LM_INFO, "Empty Message\n"));
+ ACE_CLASSIX_Msg msg1;
+ msg1.dump();
+
+ char buf[] ="This is a test message";
+ int size = sizeof (buf);
+ ACE_DEBUG((LM_INFO, "%s(size = %d)\n", buf, size));
+ ACE_CLASSIX_Msg msg2(buf, size);
+ msg2.dump();
+
+
+ ACE_END_TEST;
+ return 0;
+}
+
diff --git a/tests/CLASSIX/README b/tests/CLASSIX/README
new file mode 100644
index 00000000000..c630f42424d
--- /dev/null
+++ b/tests/CLASSIX/README
@@ -0,0 +1,25 @@
+Addr_Test.cpp
+ tests ACE_CLASSIX_Addr class
+
+Group_Test.cpp
+ tests ACE_CLASSIX_Group class and its subclasses
+
+Reactor_Test.cpp
+ tests ACE_CLASSIX_Select_Reactor class
+ tests timeout handler mechanism
+ tests co-existance of ACE_Select_Reactor and ACE_CLASSIX_Select_Reactor classes
+
+Notify_Test.cpp
+ tests multithreading and sharing resources
+ tests notify handler mechanism
+ tests co-existance of ACE_Select_Reactor and ACE_CLASSIX_Select_Reactor classes....
+ The number of threads seem to cause CLASSIX' socket subsystem
+"over-stressed". Therefore, the tests has changed to use CLASSIX reactor only (see activating tasks in main())
+
+Stream_Test.cpp
+ tests ACE_CLASSIX_Stream class
+ tests ipcReceive() read and ipcReceive() peek mechanism
+
+CLD_Connect_Test.cpp
+ tests ACE_CLASSIX_Connector, ACE_CLASSIX_Dgram_Mcast classes
+
diff --git a/tests/CLASSIX/Reactor_Test.cpp b/tests/CLASSIX/Reactor_Test.cpp
new file mode 100644
index 00000000000..638a98a2fec
--- /dev/null
+++ b/tests/CLASSIX/Reactor_Test.cpp
@@ -0,0 +1,150 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Reactor_Test.cpp
+//
+// = DESCRIPTION
+// This is a test of the <ACE_CLASSIX_Select_Reactor> class.
+// based on $ACE_ROOT/tests/MT_Reactor_Timer_Test.cpp
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "Reactor_Test.h"
+#include "CLASSIX/Reactor.h"
+
+
+
+static ACE_Reactor *the_reactor;
+
+Time_Handler::Time_Handler (void)
+{
+ for (int i = 0;
+ i < Time_Handler::TIMER_SLOTS;
+ this->timer_id_[i++] = -1)
+ continue;
+}
+
+// Set up initial timer conditions.
+
+void
+Time_Handler::setup (void)
+{
+ this->timer_id_[1] = the_reactor->schedule_timer (this,
+ (const void *) 1,
+ ACE_Time_Value (5));
+}
+
+
+// In the secondary thread, set a heartbeat timer to go off every
+// second. The heartbeat checks the status of things to be sure
+// they're being set and expired correctly.
+
+int
+Time_Handler::svc (void)
+{
+ ACE_Time_Value backstop (30);
+
+ this->timer_id_[2] = the_reactor->schedule_timer(this,
+ (const void *) 2,
+ ACE_Time_Value (3));
+ this->my_reactor_.owner (ACE_OS::thr_self ());
+ this->my_reactor_.schedule_timer (this, (const void *) 0,
+ ACE_Time_Value (1),
+ ACE_Time_Value (1));
+
+ while (!ACE_Reactor::event_loop_done())
+ {
+ int result = this->my_reactor_.handle_events (backstop);
+ if (result == -1)
+ break;
+ ACE_Thread::yield();
+ }
+
+ ACE_DEBUG((LM_DEBUG, "(%T(%t) heartbeat's event loop ended\n"));
+
+ return 0;
+}
+
+int
+Time_Handler::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ long time_tag = long (arg);
+ ACE_UNUSED_ARG(tv);
+
+ if (time_tag == 0)
+ { // Heartbeat.
+ int i;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): heartbeat...\n"));
+ // See if all of the timers have fired. If so, leave the thread's
+ // reactor loop which will exit the thread and end the test.
+
+ for (i = 0; i < Time_Handler::TIMER_SLOTS; i++)
+ if (this->timer_id_[i] != -1)
+ break;
+
+ if (i == Time_Handler::TIMER_SLOTS)
+ { // All timers should be gone.
+
+ // Cancel heartbeat.
+ ACE_ASSERT (this->my_reactor_.cancel_timer (this) == 1);
+
+ // Shouldn't be any.
+ ACE_ASSERT (the_reactor->cancel_timer (this) == 0);
+ this->my_reactor_.end_event_loop ();
+ }
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): ...heartbeat\n"));
+ return 0;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): Timer #%d (id #%d) expired\n",
+ time_tag,
+ this->timer_id_[time_tag]));
+
+ ACE_ASSERT (this->timer_id_[time_tag] != -1);
+ this->timer_id_[time_tag] = -1;
+
+ return 0;
+}
+
+
+//===============================================================//
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("Reactor_Test");
+
+ // CLASSIX environment initialization
+ ACE_CLASSIX_OS classix;
+ the_reactor = ACE_Reactor::instance();
+ Time_Handler other_thread;
+
+
+ // Set up initial set of timers.
+ other_thread.setup ();
+
+ other_thread.activate (THR_NEW_LWP | THR_JOINABLE);
+ the_reactor->run_event_loop ();
+ ACE_DEBUG((LM_DEBUG, "(%t) main thread's event loop ended\n"));
+ other_thread.wait ();
+
+
+ ACE_END_TEST;
+ return 0;
+}
+
diff --git a/tests/CLASSIX/Reactor_Test.h b/tests/CLASSIX/Reactor_Test.h
new file mode 100644
index 00000000000..11b19cb7df1
--- /dev/null
+++ b/tests/CLASSIX/Reactor_Test.h
@@ -0,0 +1,52 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Reactor_Test.h
+//
+// = DESCRIPTION
+// This file contains class definitions needed for template
+// instantiation in the Reactor_Test.cpp file.
+// Based on $ACE_ROOT/tests/MT_Reactor_Timer_Test.h
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#if !defined (__CLASSIX_REACTOR_TEST_H)
+#define __CLASSIX_REACTOR_TEST_H
+
+#include "ace/Reactor.h"
+#include "ace/Task.h"
+
+class Time_Handler : public ACE_Task<ACE_SYNCH>
+{
+public:
+ Time_Handler (void);
+
+ void setup (void);
+
+ virtual int svc (void);
+ // Run by a daemon thread to handle deferred processing.
+
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg);
+
+private:
+ enum
+ {
+ TIMER_SLOTS = 10
+ };
+
+ long timer_id_[TIMER_SLOTS];
+ int step_;
+ ACE_Reactor my_reactor_;
+};
+
+#endif /* __CLASSIX_REACTOR_TEST_H */
diff --git a/tests/CLASSIX/SOCK_Test.cpp b/tests/CLASSIX/SOCK_Test.cpp
new file mode 100644
index 00000000000..1600eaca6a4
--- /dev/null
+++ b/tests/CLASSIX/SOCK_Test.cpp
@@ -0,0 +1,99 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// CLASSIX_SOCK_Test.cpp
+//
+// = DESCRIPTION
+// This is a test of the <IPP_CLASSIX_Addr> class.
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#include "tests/test_config.h"
+#include "wrapper/CLASSIX_Addr.h"
+#include "wrapper/CLASSIX_SAP.h"
+
+class testSap : public ACE_CLASSIX_SAP
+{
+public:
+ testSap(): ACE_CLASSIX_SAP() {}
+ testSap(const ACE_Addr& theAddr) : ACE_CLASSIX_SAP(theAddr) {}
+
+ ~testSap() {ACE_DEBUG((LM_DEBUG, "~testSap()\n"));}
+};
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("SOCK_Test");
+
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "... test virtual destructor...\n"));
+ testSap *n1 = new testSap();
+ ACE_CLASSIX_SAP *n2 = n1;
+ delete n2;
+
+ /* ================================================================== */
+ ACE_DEBUG((LM_INFO, "... ACE_CLASSIX_Addr...\n"));
+ ACE_CLASSIX_Addr a1;
+ a1.set();
+ ACE_DEBUG((LM_INFO, "Addr a1:"));
+ a1.dump();
+
+ KnUniqueId k2;
+ ::portCreate(K_MYACTOR, &k2);
+ int p2 = ::portLi(&k2);
+ ACE_CLASSIX_Addr a2(k2);
+ ACE_DEBUG((LM_INFO, "Addr a2(ipc port id = %d)\n", p2));
+ a2.dump();
+
+ KnUniqueId k3;
+ ::portCreate(K_MYACTOR, &k3);
+ int p3 = ::portLi(&k3);
+ ACE_CLASSIX_Addr a3(p3);
+ ACE_DEBUG((LM_INFO, "Addr a3(ipc port id = %d)\n", p3));
+ a3.dump();
+
+ ACE_CLASSIX_Addr a4(a1);
+ if (a4 == a1)
+ ACE_DEBUG((LM_INFO, "OK: Addr a4 == a1\n"));
+ else
+ ACE_ERROR((LM_ERROR, "Error: Addr a4 != a1\n"));
+
+ if (a4 != a2)
+ ACE_DEBUG((LM_INFO, "OK: Addr a4 != a2\n"));
+ else
+ ACE_ERROR((LM_ERROR, "Error: Addr a4 == a2\n"));
+
+ /* ================================================================== */
+
+ ACE_DEBUG((LM_INFO, "\n... ACE_CLASSIX...\n"));
+ testSap sap1;
+ sap1.set_local_addr(a1);
+ ACE_CLASSIX_Addr b1;
+ sap1.get_local_addr(b1);
+ if (b1 != a1)
+ ACE_ERROR((LM_ERROR, "Error: sap address"));
+ sap1.dump();
+
+
+ testSap sap2(a2);
+ ACE_CLASSIX_Addr b2;
+ sap2.get_local_addr(b2);
+ if (b2 != a2)
+ ACE_ERROR((LM_ERROR, "Error: sap address"));
+ sap2.dump();
+
+
+ ACE_END_TEST;
+ return 0;
+}
+
diff --git a/tests/CLASSIX/Select_Reactor_Test.cpp b/tests/CLASSIX/Select_Reactor_Test.cpp
new file mode 100644
index 00000000000..c39f9e425ca
--- /dev/null
+++ b/tests/CLASSIX/Select_Reactor_Test.cpp
@@ -0,0 +1,166 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// MT_Reactor_Timer_Test.cpp
+//
+// = DESCRIPTION
+// This is a simple test that illustrates the timer mechanism of
+// the reactor scheduling timers, handling expired timers and
+// cancelling scheduled timers from multiple threads.
+// No command line arguments are needed to run the test.
+//
+// = AUTHOR
+// Steve Huston
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "Select_Reactor_Test.h"
+
+#if defined (ACE_HAS_THREADS)
+
+static ACE_Reactor *the_reactor;
+
+Time_Handler::Time_Handler (void)
+{
+ for (int i = 0;
+ i < Time_Handler::TIMER_SLOTS;
+ this->timer_id_[i++] = -1)
+ continue;
+}
+
+// Set up initial timer conditions.
+
+void
+Time_Handler::setup (void)
+{
+ this->timer_id_[1] = the_reactor->schedule_timer (this,
+ (const void *) 1,
+ ACE_Time_Value (5));
+}
+
+
+// In the secondary thread, set a heartbeat timer to go off every
+// second. The heartbeat checks the status of things to be sure
+// they're being set and expired correctly.
+
+int
+Time_Handler::svc (void)
+{
+ ACE_Time_Value backstop (30);
+
+ this->timer_id_[2] = the_reactor->schedule_timer(this,
+ (const void *) 2,
+ ACE_Time_Value (3));
+ ACE_thread_t tid;
+ this->my_reactor_.owner(&tid);
+ ACE_DEBUG((LM_DEBUG, "((%t) hearbeat reactor's owner was %d\n", tid));
+ this->my_reactor_.owner (ACE_Thread::self ());
+ this->my_reactor_.owner(&tid);
+ ACE_DEBUG((LM_DEBUG, "((%t) hearbeat reactor's owner is %d\n", tid));
+
+ long id = this->my_reactor_.schedule_timer (this, (const void *) 0,
+ ACE_Time_Value (1),
+ ACE_Time_Value (1));
+ this->my_reactor_.owner(&tid);
+
+ while (!ACE_Reactor::event_loop_done())
+ {
+ int result = this->my_reactor_.handle_events (backstop);
+ if (result == -1)
+ break;
+ }
+
+ ACE_DEBUG((LM_DEBUG, "(%T(%t) exit from heartbeat\n"));
+ return 0;
+}
+
+int
+Time_Handler::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ long time_tag = long (arg);
+ ACE_UNUSED_ARG(tv);
+
+ if (time_tag == 0)
+ { // Heartbeat.
+ int i;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): heartbeat\n"));
+ // See if all of the timers have fired. If so, leave the thread's
+ // reactor loop which will exit the thread and end the test.
+
+ for (i = 0; i < Time_Handler::TIMER_SLOTS; i++)
+ if (this->timer_id_[i] != -1)
+ break;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): heartbeat done: time slot = %d\n", i));
+ if (i == Time_Handler::TIMER_SLOTS)
+ { // All timers should be gone.
+
+ // Cancel heartbeat.
+ ACE_ASSERT (this->my_reactor_.cancel_timer (this) == 1);
+
+ // Shouldn't be any.
+ ACE_ASSERT (the_reactor->cancel_timer (this) == 0);
+ this->my_reactor_.end_event_loop ();
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): event loop ended\n"));
+ }
+ return 0;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): Timer #%d (id #%d) expired\n",
+ time_tag,
+ this->timer_id_[time_tag]));
+
+ ACE_ASSERT (this->timer_id_[time_tag] != -1);
+ this->timer_id_[time_tag] = -1;
+
+ return 0;
+}
+
+#endif /* ACE_HAS_THREADS */
+
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("Select_Reactor_Test");
+
+#if defined (ACE_HAS_THREADS)
+
+ the_reactor = ACE_Reactor::instance ();
+ Time_Handler other_thread;
+
+
+ // Set up initial set of timers.
+ other_thread.setup ();
+
+ #if 0
+ the_reactor->schedule_timer (&other_thread,
+ (const void *) 1,
+ ACE_Time_Value (5));
+ #endif /* 0 */
+
+ other_thread.activate (THR_NEW_LWP | THR_JOINABLE);
+ the_reactor->run_event_loop ();
+ ACE_DEBUG ((LM_DEBUG,
+ "%T (%t): waiting for thread to exit\n"));
+ other_thread.wait ();
+#else
+ ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n"));
+#endif /* ACE_HAS_THREADS */
+
+ ACE_END_TEST;
+ return 0;
+}
diff --git a/tests/CLASSIX/Select_Reactor_Test.h b/tests/CLASSIX/Select_Reactor_Test.h
new file mode 100644
index 00000000000..7c663b59ab5
--- /dev/null
+++ b/tests/CLASSIX/Select_Reactor_Test.h
@@ -0,0 +1,51 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// MT_Reactor_Timer_Test.h
+//
+// = DESCRIPTION
+// This file contains class definitions needed for template
+// instantiation in the MT_Reactor_Timer_Test.cpp file.
+//
+// = AUTHOR
+// Steve Huston
+//
+// ============================================================================
+
+#if !defined (__MT_REACTOR_TIMER_TEST_H)
+#define __MT_REACTOR_TIMER_TEST_H
+
+#include "ace/Reactor.h"
+#include "ace/Task.h"
+
+class Time_Handler : public ACE_Task<ACE_SYNCH>
+{
+public:
+ Time_Handler (void);
+
+ void setup (void);
+
+ virtual int svc (void);
+ // Run by a daemon thread to handle deferred processing.
+
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg);
+
+private:
+ enum
+ {
+ TIMER_SLOTS = 10
+ };
+
+ long timer_id_[TIMER_SLOTS];
+ int step_;
+ ACE_Reactor my_reactor_;
+};
+
+#endif /* __MT_REACTOR_TIMER_TEST_H */
diff --git a/tests/CLASSIX/Stream_Test.cpp b/tests/CLASSIX/Stream_Test.cpp
new file mode 100644
index 00000000000..40c13485c27
--- /dev/null
+++ b/tests/CLASSIX/Stream_Test.cpp
@@ -0,0 +1,110 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Stream_Test.cpp
+//
+// = DESCRIPTION
+// This is a test of the <IPP_CLASSIX_Addr> class.
+//
+// = AUTHOR
+// Wei Chiang
+//
+// ============================================================================
+
+#include "tests/test_config.h"
+#include "CLASSIX/Stream.h"
+
+#define RCV_DELAY 1000 /* We should NOT wait in ipcReceive */
+
+static char sndBody[] = "The sea is calm, the tide is full ...\n";
+static char rcvAnnex[K_CMSGANNEXSIZE];
+static char rcvBody[1000];
+
+int
+main (int, char *[])
+{
+ ACE_START_TEST ("Stream_Test");
+
+ /* ================================================================== */
+ ACE_CLASSIX_Port_Core remote_port;
+
+ // Sender's socket
+ // Use my default port as the sending address
+ ACE_CLASSIX_Stream send(remote_port);
+
+ ACE_CLASSIX_Stream rcv(send.local_sap().get_addr(),
+ ACE_CLASSIX_Port(remote_port));
+ // make the rcv's port be one of the multiple receive ports
+ if (rcv.selectable() < 0)
+ ACE_DEBUG((LM_DEBUG, "failed to make the port selectable\n"));
+
+ send.open_writer();
+
+ ACE_DEBUG((LM_DEBUG, "send and block on receive....\n"));
+ if (send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody))
+ {
+ // Receiver's Socket
+ int rslt = rcv.ipcRecv(rcvBody, 1000);
+ if (rslt == sizeof (sndBody))
+ ACE_DEBUG((LM_DEBUG, "received %s\n", rcvBody));
+ else
+ ACE_DEBUG((LM_ERROR, "???? Error in ipcReceive():%d\n", rslt));
+ }
+ else
+ {
+ ACE_ERROR((LM_ERROR, "(%t)|%p\n", "???? Error in send_n()\n"));
+ }
+
+ ACE_DEBUG((LM_DEBUG, "send, peek then block on receive....\n"));
+ if (send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody))
+ {
+ // Receiver's Socket
+ // int rslt = rcv.recv(rcvBody, 1000, MSG_PEEK);
+ // Equivalent to rcv.peek()
+ int rslt = rcv.peek();
+ if (rslt < 0)
+ ACE_DEBUG((LM_ERROR, "???? Error while peeking :%d\n", rslt));
+ else
+ {
+ char *buf = new char(rslt);
+ if (int n = rcv.recv(buf, rslt) == rslt)
+ ACE_DEBUG((LM_DEBUG, "received %s\n", buf));
+ else
+ ACE_DEBUG((LM_ERROR, "???? Error in ipcReceive(): %d\n", n));
+ delete buf;
+ }
+ }
+ else
+ {
+ ACE_DEBUG((LM_ERROR, "???? Error in send_n()\n"));
+ }
+
+ ACE_DEBUG((LM_DEBUG, "test recv_n()....\n"));
+ if (send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody) &&
+ send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody))
+ {
+ // Receiver's Socket
+
+ int rslt = rcv.ipcRecv_n(rcvBody, 2*sizeof (sndBody) - 10);
+ if (rslt == (2 * sizeof (sndBody) -10))
+ {
+ rcvBody[rslt] = '\0'; // For %s printout format
+ ACE_DEBUG((LM_DEBUG, "received %d byte: %s + %s\n", rslt,
+ rcvBody, rcvBody + sizeof(sndBody)));
+ }
+ else
+ ACE_DEBUG((LM_ERROR, "???(%P|%t) %p\n", "ipcRecv_n()"));
+ }
+ else
+ ACE_DEBUG((LM_ERROR, "???(%P|%t) %p\n", "ipcRecv_n()"));
+
+ ACE_END_TEST;
+ return 0;
+}
+
diff --git a/tests/CLASSIX/test_config.h b/tests/CLASSIX/test_config.h
new file mode 100644
index 00000000000..a1988fec7b9
--- /dev/null
+++ b/tests/CLASSIX/test_config.h
@@ -0,0 +1,272 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+// = FILENAME
+// test_config.h
+//
+// = AUTHOR
+// Prashant Jain <pjain@cs.wustl.edu>, Tim Harrison
+// <harrison@cs.wustl.edu>, and David Levine <levine@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_TEST_CONFIG_H)
+#define ACE_TEST_CONFIG_H
+
+// This first #undef protects against command-line definitions.
+#undef ACE_NDEBUG
+#include "ace/OS.h"
+#include "ace/streams.h"
+
+// The second #undef protects against being reset in a config.h file.
+#undef ACE_NDEBUG
+
+#if !defined (ACE_HAS_TEMPLATE_SPECIALIZATION)
+class KEY
+// ============================================================================
+// = TITLE
+// Define a key for use with the Map_Manager_Test.
+//
+// = DESCRIPTION
+// This class is put into the test_config.h header file to work
+// around AIX C++ compiler "features" related to template
+// instantiation... It is only used by Map_Manager_Test.cpp
+// ============================================================================
+{
+public:
+ KEY (size_t v = 0): value_ (v)
+ { }
+
+ size_t hash (void) const { return this->value_; }
+ operator size_t () const { return this->value_; }
+
+private:
+ size_t value_;
+};
+#else
+typedef size_t KEY;
+#endif /* ACE_HAS_TEMPLATE_SPECIALIZATION */
+
+#if defined (ACE_WIN32)
+
+#define ACE_DEFAULT_TEST_FILE_A "C:\\temp\\ace_test_file"
+#define ACE_TEMP_FILE_NAME_A "C:\\temp\\ace_temp_file"
+#define ACE_LOG_DIRECTORY_A "C:\\temp\\log\\"
+#define MAKE_PIPE_NAME_A(X) "\\\\.\\pipe\\"#X
+
+#define ACE_DEFAULT_TEST_FILE_W L"C:\\temp\\ace_test_file"
+#define ACE_TEMP_FILE_NAME_W L"C:\\temp\\ace_temp_file"
+#define ACE_LOG_DIRECTORY_W L"C:\\temp\\log\\"
+#define MAKE_PIPE_NAME_W(X) L"\\\\.\\pipe\\"#X
+
+#else
+
+#define ACE_DEFAULT_TEST_FILE_A "/tmp/ace_test_file"
+#define ACE_TEMP_FILE_NAME_A "/tmp/ace_temp_file"
+#define ACE_LOG_DIRECTORY_A "log/"
+#define MAKE_PIPE_NAME_A(X) X
+
+#if defined (ACE_HAS_UNICODE)
+#define ACE_DEFAULT_TEST_FILE_W L"/tmp/ace_test_file"
+#define ACE_TEMP_FILE_NAME_W L"/tmp/ace_temp_file"
+#define ACE_LOG_DIRECTORY_W L"log/"
+#define MAKE_PIPE_NAME_W(X) L##X
+#else
+#define ACE_DEFAULT_TEST_FILE_W "/tmp/ace_test_file"
+#define ACE_TEMP_FILE_NAME_W "/tmp/ace_temp_file"
+#define ACE_LOG_DIRECTORY_W "log/"
+#define MAKE_PIPE_NAME_W(X) X
+#endif /* ACE_HAS_UNICODE */
+
+#endif /* ACE_WIN32 */
+
+#if defined (UNICODE)
+#define ACE_DEFAULT_TEST_FILE ACE_DEFAULT_TEST_FILE_W
+#define ACE_TEMP_FILE_NAME ACE_TEMP_FILE_NAME_W
+#define ACE_LOG_DIRECTORY ACE_LOG_DIRECTORY_W
+#define MAKE_PIPE_NAME MAKE_PIPE_NAME_W
+#else
+#define ACE_DEFAULT_TEST_FILE ACE_DEFAULT_TEST_FILE_A
+#define ACE_TEMP_FILE_NAME ACE_TEMP_FILE_NAME_A
+#define ACE_LOG_DIRECTORY ACE_LOG_DIRECTORY_A
+#define MAKE_PIPE_NAME MAKE_PIPE_NAME_A
+#endif /* UNICODE */
+
+#define ACE_START_TEST(NAME) \
+ const char *program = NAME; \
+ ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM); \
+ if (ace_file_stream.set_output (program) != 0) \
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_output failed"), -1); \
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting %s test at %D\n", program));
+
+#define ACE_END_TEST \
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Ending %s test at %D\n", program)); \
+ ace_file_stream.close ()
+
+#define ACE_APPEND_LOG(NAME) \
+ const char *program = NAME; \
+ ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM); \
+ ace_file_stream.close (); \
+ if (ace_file_stream.set_output (program, 1) != 0) \
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_output failed"), -1); \
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Starting %s test at %D\n", program));
+
+#define ACE_END_LOG \
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Ending %s test at %D\n\n", program)); \
+ ace_file_stream.close ();
+
+#if defined (VXWORKS)
+ // This is the only way I could figure out to avoid an error
+ // about attempting to unlink a non-existant file.
+#define ACE_INIT_LOG(NAME) \
+ char temp[MAXPATHLEN]; \
+ ACE_OS::sprintf (temp, "%s%s%s", \
+ ACE_LOG_DIRECTORY_A, \
+ ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR_A), \
+ ".log"); \
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Deleting old log file %s (if any)\n\n", temp)); \
+ int fd_init_log; \
+ if ((fd_init_log = ACE_OS::open (temp, \
+ O_WRONLY | O_CREAT, 0x644)) != ERROR) \
+ { \
+ ACE_OS::close (fd_init_log); \
+ ACE_OS::unlink (temp); \
+ }
+#else /* ! VXWORKS */
+#define ACE_INIT_LOG(NAME) \
+ char temp[MAXPATHLEN]; \
+ ACE_OS::sprintf (temp, "%s%s%s", \
+ ACE_LOG_DIRECTORY_A, \
+ ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR_A), \
+ ".log"); \
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Deleting old log file %s (if any)\n\n", temp)); \
+ ACE_OS::unlink (temp);
+#endif /* ! VXWORKS */
+
+const size_t ACE_NS_MAX_ENTRIES = 1000;
+const size_t ACE_DEFAULT_USECS = 1000;
+const size_t ACE_MAX_TIMERS = 4;
+const size_t ACE_MAX_THREADS = 4;
+const size_t ACE_MAX_DELAY = 10;
+const size_t ACE_MAX_INTERVAL = 0;
+const size_t ACE_MAX_ITERATIONS = 10;
+const size_t ACE_MAX_PROCESSES = 10;
+const size_t ACE_MAX_CLIENTS = 30;
+
+char ACE_ALPHABET[] = "abcdefghijklmnopqrstuvwxyz";
+
+class ACE_Test_Output
+{
+public:
+ ACE_Test_Output (void);
+ ~ACE_Test_Output (void);
+ int set_output (const char *filename, int append = 0);
+ ofstream *output_file (void);
+ void close (void);
+
+private:
+ ofstream output_file_;
+};
+
+static ACE_Test_Output ace_file_stream;
+
+ACE_Test_Output::ACE_Test_Output (void)
+{
+}
+
+ACE_Test_Output::~ACE_Test_Output (void)
+{
+}
+
+int
+ACE_Test_Output::set_output (const char *filename, int append)
+{
+ char temp[MAXPATHLEN];
+ // Ignore the error value since the directory may already exist.
+
+ char *test_dir = ACE_OS::getenv ("ACE_TEST_DIR");
+
+ if (test_dir == 0)
+ test_dir = "";
+
+ ACE_OS::sprintf (temp,
+ "%s%s%s%s",
+ test_dir,
+ ACE_LOG_DIRECTORY_A,
+ ACE::basename (filename, ACE_DIRECTORY_SEPARATOR_CHAR_A),
+ ".log");
+
+#if defined (VXWORKS)
+ // This is the only way I could figure out to avoid a console warning
+ // about opening an existing file (w/o O_CREAT), or attempting to unlink
+ // a non-existant one.
+ int fd;
+ if ((fd = ACE_OS::open (temp, O_WRONLY | O_CREAT, 0x644)) != ERROR)
+ {
+ ACE_OS::close (fd);
+ ACE_OS::unlink (temp);
+ }
+#else /* ! VXWORKS */
+ // This doesn't seem to work on VxWorks if the directory doesn't
+ // exist: it creates a plain file instead of a directory. If the
+ // directory does exist, it causes a wierd console error message
+ // about "cat: input error on standard input: Is a directory". So,
+ // VxWorks users must create the directory manually.
+ ACE_OS::mkdir (ACE_LOG_DIRECTORY_A);
+#endif /* ! VXWORKS */
+
+ int flags = ios::out;
+ if (append)
+ flags |= ios::app;
+ else
+ flags |= ios::trunc;
+
+ this->output_file_.open (temp, flags);
+ if (this->output_file_.bad ())
+ {
+ return -1;
+ }
+
+ ACE_LOG_MSG->msg_ostream (ace_file_stream.output_file ());
+ ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER );
+ ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM);
+
+ return 0;
+}
+
+ofstream *
+ACE_Test_Output::output_file (void)
+{
+ return &this->output_file_;
+}
+
+void
+ACE_Test_Output::close (void)
+{
+ this->output_file_.flush ();
+ this->output_file_.close ();
+}
+
+void
+randomize (int array[], size_t size)
+{
+ size_t i;
+
+ for (i = 0; i < size; i++)
+ array [i] = i;
+
+ ACE_OS::srand (ACE_OS::time (0L));
+
+ // Generate an array of random numbers from 0 .. size - 1.
+
+ for (i = 0; i < size; i++)
+ {
+ int index = ACE_OS::rand() % size--;
+ int temp = array [index];
+ array [index] = array [size];
+ array [size] = temp;
+ }
+}
+
+#endif /* ACE_TEST_CONFIG_H */