[Xorp-hackers] Libxorp proposal: service.{hh,cc}
Orion Hodson
orion@icir.org
Thu, 09 Oct 2003 08:19:22 -0700
This is a multipart MIME message.
--==_Exmh_16833281770
Content-Type: text/plain; charset=us-ascii
Attached is a patch for libxorp to add some new classes for "services". A
service is a class that provides some functionality to a process and requires
transition time to startup, shutdown, etc. The code is fairly trivial, it
just keeps track of state, and nominally informs an observer.
Since I've found myself re-implementing this pattern in multiple places in RIP
and think it might be useful other places, I've factored it out. The code has
a little bit of fat relative to the functionality RIP uses, ie PAUSE, PAUSING,
RESUMING states, but that may be useful elsewhere.
The is a patch below if you want to take a look. Comments welcome.
Cheers
- Orion
--==_Exmh_16833281770
Content-Type: text/plain ; name="service.diff"; charset=us-ascii
Content-Description: service.diff
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="service.diff"
Index: libxorp/service.hh
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: libxorp/service.hh
diff -N libxorp/service.hh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libxorp/service.hh 9 Oct 2003 07:04:56 -0000
@@ -0,0 +1,222 @@
+// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
+
+// Copyright (c) 2001-2003 International Computer Science Institute
+//
+// Permission is hereby granted, free of charge, to any person obtaining=
a
+// copy of this software and associated documentation files (the "Softwa=
re")
+// to deal in the Software without restriction, subject to the condition=
s
+// listed in the XORP LICENSE file. These conditions include: you must
+// preserve this copyright notice, and you cannot mention the copyright
+// holders in advertising related to the Software without their permissi=
on.
+// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. Th=
is
+// notice is a summary of the XORP LICENSE file; the license in that fil=
e is
+// legally binding.
+
+// $XORP$
+
+#ifndef __LIBXORP_SERVICE_HH__
+#define __LIBXORP_SERVICE_HH__
+
+/**
+ * Enumeration of states objects derived from ServiceBase may be in.
+ */
+enum ServiceStatus {
+ READY =3D 0x001, // Ready for startup
+ STARTING =3D 0x002, // Starting up
+ RUNNING =3D 0x004, // Running, service operational
+ PAUSING =3D 0x008, // Transitioning to paused state
+ PAUSED =3D 0x010, // Paused, non-operational
+ RESUMING =3D 0x020, // Resuming from pause
+ SHUTTING_DOWN =3D 0x040, // Transitioning to shutdown
+ SHUTDOWN =3D 0x080, // Shutdown, non-operational
+ FAILED =3D 0x100, // Failed, non-operational
+ ALL =3D READY | STARTING | RUNNING |
+ PAUSING | PAUSED | RESUMING |
+ SHUTTING_DOWN | SHUTDOWN | FAILED
+};
+
+/**
+ * Get text description of enumerated service status.
+ *
+ * @param s service status to recover name for.
+ */
+const char* service_status_name(ServiceStatus s);
+
+class ServiceChangeObserverBase;
+
+/**
+ * @short Base class for Services.
+ *
+ * This class provides a base for services within Xorp processes. A
+ * service instance is an entity that can logically started and
+ * stopped and typically needs some asynchronous processing in order
+ * to start and stop. An example service within a routing process
+ * would be a RIB communicator service, which needs to co-ordinate
+ * with the RIB which is within a different process and may be on a
+ * different machine.
+ *
+ * A service may be started and shutdown by calling @ref startup() and
+ * @ref shutdown(). The status of a service may be determined by
+ * calling @ref status(). Additional notes on the current status may be=
+ * obtained by calling @ref status_note().
+ *
+ * Synchronous service status changes may be received through the @ref
+ * ServiceChangeObserverBase class. Instances of objects derived from
+ * this class can register for status change notifications in a
+ * Service instance by calling @ref set_observer().
+ */
+class ServiceBase {
+public:
+ ServiceBase();
+
+ virtual ~ServiceBase() =3D 0;
+
+ /**
+ * Start service. Service should transition from READY to
+ * STARTING immediately and onto RUNNING or FAILED in the near
+ * future.
+ */
+ virtual void startup() =3D 0;
+
+ /**
+ * Shutdown service. Service should transition from RUNNING to
+ * SHUTTING_DOWN immediately and onto SHUTDOWN or FAILED in the
+ * near future.
+ */
+ virtual void shutdown() =3D 0;
+
+ /**
+ * Reset service. Service should transition in READY from
+ * whichever state it is in.
+ *
+ * The default implementation always returns false as there is no
+ * default behaviour.
+ *
+ * @return true on success, false on failure.
+ */
+ virtual bool reset();
+
+ /**
+ * Pause service. Service should transition from RUNNING to
+ * PAUSING and asynchronously into PAUSED.
+ *
+ * The default implementation always returns false as there is no
+ * default behaviour.
+ *
+ * @return true on success, false on failure.
+ */
+ virtual bool pause();
+
+ /**
+ * Resume paused service. Service should transition from PAUSED
+ * to PAUSING and asynchronously into RUNNING.
+ *
+ * The default implementation always returns false as there is no
+ * default behaviour.
+ *
+ * @return true on success, false on failure.
+ */
+ virtual bool resume();
+
+ /**
+ * Get the current status.
+ */
+ inline ServiceStatus status() const { return _status; }
+
+ /**
+ * Get annotation associated with current status. The annotation wh=
en
+ * set is an explanation of the state, ie "waiting for Y"
+ */
+ inline const string& status_note() const { return _note; }
+
+ /**
+ * Get a character representation of the current service status.
+ */
+ const char* status_name() const;
+
+ /**
+ * Set service status change observer. The observer will receive
+ * synchronous notifications of changes in service state.
+ *
+ * @param so service change observer to add.
+ * @return true on success, false if an observer is already set.
+ */
+ bool set_observer(ServiceChangeObserverBase* so);
+
+ /**
+ * Remove service status change observer.
+ *
+ * @param so observer to remove.
+ * @return true on success, false if supplied observer does match
+ * the last set observer.
+ */
+ bool unset_observer(ServiceChangeObserverBase* so);
+
+protected:
+ /**
+ * Set current status.
+ *
+ * @param status new status.
+ * @param note comment on new service status.
+ */
+ void set_status(ServiceStatus status, const string& note);
+
+ /**
+ * Set current status and clear status note.
+ *
+ * @param status new status.
+ */
+ void set_status(ServiceStatus status);
+
+protected:
+ ServiceStatus _status;
+ string _note;
+ ServiceChangeObserverBase* _observer;
+};
+
+/**
+ * @short Base class for service status change observer.
+ */
+class ServiceChangeObserverBase {
+public:
+ virtual ~ServiceChangeObserverBase() =3D 0;
+
+ virtual void status_change(ServiceBase* service,
+ ServiceStatus old_status,
+ ServiceStatus new_status) =3D 0;
+};
+
+/**
+ * @short Selective Change Observer.
+ *
+ * Forwards limited subset of status changes to a status change observer=
=2E
+ */
+class ServiceFilteredChangeObserver
+ : public ServiceChangeObserverBase {
+public:
+ /**
+ * Constructor.
+ *
+ * Only changes from the states represented in @ref from_mask to
+ * the states represented in @ref to_mask are reported.
+ *
+ * @param child recipient of status changes.
+ * @param from_mask mask of states left to trigger changes.
+ * @param to_mask mask of states entered to trigger changes.
+ */
+ ServiceFilteredChangeObserver(ServiceChangeObserverBase* child,
+ ServiceStatus from_mask,
+ ServiceStatus to_mask);
+
+protected:
+ void status_change(ServiceBase* service,
+ ServiceStatus old_status,
+ ServiceStatus new_status);
+
+protected:
+ ServiceChangeObserverBase* _child;
+ ServiceStatus _from_mask;
+ ServiceStatus _to_mask;
+};
+
+#endif // __LIBXORP_SERVICE_HH__
Index: libxorp/service.cc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: libxorp/service.cc
diff -N libxorp/service.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libxorp/service.cc 9 Oct 2003 07:04:56 -0000
@@ -0,0 +1,156 @@
+// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
+
+// Copyright (c) 2001-2003 International Computer Science Institute
+//
+// Permission is hereby granted, free of charge, to any person obtaining=
a
+// copy of this software and associated documentation files (the "Softwa=
re")
+// to deal in the Software without restriction, subject to the condition=
s
+// listed in the XORP LICENSE file. These conditions include: you must
+// preserve this copyright notice, and you cannot mention the copyright
+// holders in advertising related to the Software without their permissi=
on.
+// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. Th=
is
+// notice is a summary of the XORP LICENSE file; the license in that fil=
e is
+// legally binding.
+
+#ident "$XORP$"
+
+#include "config.h"
+#include <string>
+
+#include "service.hh"
+
+// ---------------------------------------------------------------------=
-------
+// ServiceStatus related
+
+const char*
+service_status_name(ServiceStatus s)
+{
+ switch (s) {
+ case READY: return "Ready";
+ case STARTING: return "Starting";
+ case RUNNING: return "Running";
+ case PAUSING: return "Pausing";
+ case PAUSED: return "Paused";
+ case RESUMING: return "Resuming";
+ case SHUTTING_DOWN: return "Shutting down";
+ case SHUTDOWN: return "Shutdown";
+ case FAILED: return "Failed";
+ case ALL: return "All"; // Invalid
+ }
+ return "Unknown";
+}
+
+// ---------------------------------------------------------------------=
-------
+// ServiceBase implmentation
+
+ServiceBase::ServiceBase()
+ : _status(READY), _observer(0)
+{
+}
+
+ServiceBase::~ServiceBase()
+{
+}
+
+bool
+ServiceBase::reset()
+{
+ return false;
+}
+
+bool
+ServiceBase::pause()
+{
+ return false;
+}
+
+bool
+ServiceBase::resume()
+{
+ return false;
+}
+
+=0C
+const char*
+ServiceBase::status_name() const
+{
+ return service_status_name(_status);
+}
+
+bool
+ServiceBase::set_observer(ServiceChangeObserverBase* so)
+{
+ if (_observer) {
+ return false;
+ }
+ _observer =3D so;
+ return true;
+}
+
+bool
+ServiceBase::unset_observer(ServiceChangeObserverBase* so)
+{
+ if (_observer =3D=3D so) {
+ _observer =3D 0;
+ return true;
+ }
+ return false;
+}
+
+void
+ServiceBase::set_status(ServiceStatus status, const string& note)
+{
+ ServiceStatus ost =3D _status;
+ _status =3D status;
+
+ bool note_changed =3D (_note !=3D note);
+ _note =3D note;
+
+ if (_observer && (ost !=3D _status || note_changed)) {
+ _observer->status_change(this, ost, _status);
+ }
+}
+
+void
+ServiceBase::set_status(ServiceStatus status)
+{
+ ServiceStatus ost =3D _status;
+ _status =3D status;
+
+ _note.erase();
+
+ if (_observer && ost !=3D _status) {
+ _observer->status_change(this, ost, _status);
+ }
+}
+
+=0C
+// ---------------------------------------------------------------------=
-------
+// ServiceChangeObserverBase
+
+ServiceChangeObserverBase::~ServiceChangeObserverBase()
+{
+}
+
+// ---------------------------------------------------------------------=
-------
+// ServiceFilteredChangeObserver
+
+ServiceFilteredChangeObserver::ServiceFilteredChangeObserver(
+ ServiceChangeObserverBase* child,
+ ServiceStatus from,
+ ServiceStatus to
+ )
+ : _child(child), _from_mask(from), _to_mask(to)
+{
+}
+
+void
+ServiceFilteredChangeObserver::status_change(ServiceBase* service,
+ ServiceStatus old_status,
+ ServiceStatus new_status)
+{
+ if (old_status & _from_mask &&
+ new_status & _to_mask) {
+ _child->status_change(service, old_status, new_status);
+ }
+}
Index: libxorp/test_service.cc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: libxorp/test_service.cc
diff -N libxorp/test_service.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libxorp/test_service.cc 9 Oct 2003 07:04:56 -0000
@@ -0,0 +1,299 @@
+// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
+
+// Copyright (c) 2001-2003 International Computer Science Institute
+//
+// Permission is hereby granted, free of charge, to any person obtaining=
a
+// copy of this software and associated documentation files (the "Softwa=
re")
+// to deal in the Software without restriction, subject to the condition=
s
+// listed in the XORP LICENSE file. These conditions include: you must
+// preserve this copyright notice, and you cannot mention the copyright
+// holders in advertising related to the Software without their permissi=
on.
+// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. Th=
is
+// notice is a summary of the XORP LICENSE file; the license in that fil=
e is
+// legally binding.
+
+#ident "$XORP: xorp/devnotes/template.cc,v 1.2 2003/01/16 19:08:48 mjh E=
xp $"
+
+#include "config.h"
+
+#include <string>
+
+#include "eventloop.hh"
+#include "service.hh"
+
+#include "libxorp_module.h"
+#include "xlog.h"
+#include "exceptions.hh"
+
+//
+// This test is fairly straightforward. We implement two classes
+// TestService and TestServiceChangeObserver. TestService is derived
+// from ServiceBase and implements ServiceBase::startup() and
+// ServiceBase::shutdown(). With both methods, invocation sets the
+// current status to the relevant intermediate state (STARTING_UP or
+// SHUTTING_DOWN) and also sets a timer. When the timer expires it
+// sets the current state to the requested state (RUNNING or
+// SHUTDOWN). The timer expiry time is after TRANS_MS milliseconds.
+//
+// TestServiceChangeObserver assumes it is going to be informed of
+// these changes and verifies that the origin and order of changes
+// matches those it expects.
+//
+// The main body of the test is in test_main. It instantiates and
+// associates instances of TestService and TestServiceChangeObserver.
+// It uses timers to trigger the calling of TestService::startup() and
+// TestService::shutdown().
+//
+
+// ---------------------------------------------------------------------=
-------
+// Constants
+
+static const uint32_t TRANS_MS =3D 100; // Transition time (millisecs)
+static const uint32_t EXIT_MS =3D 5 * TRANS_MS; // Time to exit (millise=
cs)
+
+// ---------------------------------------------------------------------=
-------
+// Verbose output
+
+static bool s_verbose =3D false;
+
+inline bool verbose() { return s_verbose; }
+inline void set_verbose(bool v) { s_verbose =3D v; }
+
+#define verbose_log(x...) \
+do { \
+ if (verbose()) { \
+ printf("From %s:%d: ", __FILE__, __LINE__); \
+ printf(x); \
+ } \
+} while(0)
+
+=0C
+// ---------------------------------------------------------------------=
-------
+// TestService implementation
+
+class TestService : public ServiceBase
+{
+public:
+ TestService(EventLoop& e)
+ : _e(e)
+ {}
+
+ void
+ startup()
+ {
+ set_status(STARTING, "Waiting for timed start event");
+ _xt =3D _e.new_oneoff_after_ms(TRANS_MS,
+ callback(this, &TestService::go_running));
+
+ }
+
+ void
+ shutdown()
+ {
+ set_status(SHUTTING_DOWN, "Waiting for timed shutdown event");
+ _xt =3D _e.new_oneoff_after_ms(TRANS_MS,
+ callback(this, &TestService::go_shutdown));
+ }
+
+protected:
+ void go_running()
+ {
+ set_status(RUNNING);
+ }
+
+ void go_shutdown()
+ {
+ set_status(SHUTDOWN);
+ }
+
+protected:
+ EventLoop& _e;
+ XorpTimer _xt; // Timer for simulated status transitions
+};
+
+=0C
+// ---------------------------------------------------------------------=
-------
+// TestServiceChangeObserver implementation
+
+class TestServiceChangeObserver : public ServiceChangeObserverBase
+{
+public:
+ TestServiceChangeObserver(const TestService* expected_service)
+ : _s(expected_service), _cc(0), _bc(0)
+ {
+ }
+
+ void
+ status_change(ServiceBase* service,
+ ServiceStatus old_status,
+ ServiceStatus new_status)
+ {
+ if (service !=3D _s) {
+ verbose_log("Wrong service argument\n");
+ _bc++;
+ return;
+ }
+
+ ServiceStatus e_old, e_new;
+ switch (_cc++) {
+ case 0:
+ // First change expected READY -> STARTING
+ e_old =3D READY;
+ e_new =3D STARTING;
+ break;
+
+ case 1:
+ // Second change expected STARTING -> RUNNING
+ e_old =3D STARTING;
+ e_new =3D RUNNING;
+ break;
+
+ case 2:
+ // Third change expected RUNNING -> SHUTTING_DOWN
+ e_old =3D RUNNING;
+ e_new =3D SHUTTING_DOWN;
+ break;
+
+ case 3:
+ // Fourth change expected SHUTTING_DOWN -> SHUTDOWN
+ e_old =3D SHUTTING_DOWN;
+ e_new =3D SHUTDOWN;
+ break;
+ default:
+ verbose_log("%d. Too many changes.\n", _cc);
+ }
+
+ if (e_old =3D=3D old_status && e_new =3D=3D new_status) {
+ verbose_log("%d. Good transition: %s -> %s (%s)\n",
+ _cc,
+ service_status_name(e_old),
+ service_status_name(e_new),
+ service->status_note().c_str());
+ return;
+ }
+ verbose_log("%d. Bad transition: Got %s -> %s (%d) Expected %s -> %s\n"=
,
+ _cc,
+ service_status_name(old_status),
+ service_status_name(new_status),
+ service_status_name(e_old),
+ service_status_name(e_new),
+ service->status_note().c_str());
+ // Record bad change
+ _bc++;
+ }
+
+ bool changes_okay() const
+ {
+ return _cc =3D=3D 4 && _bc =3D=3D 0;
+ }
+
+protected:
+ const TestService* const _s; // Expected service
+ uint32_t _cc; // Change count
+ uint32_t _bc; // number of bad changes
+};
+
+=0C
+// ---------------------------------------------------------------------=
-------
+// Guts of Test
+
+static void
+startup_test_service(TestService* ts)
+{
+ ts->startup();
+}
+
+static void
+shutdown_test_service(TestService* ts)
+{
+ ts->shutdown();
+}
+
+static int
+run_test()
+{
+ EventLoop e;
+
+ TestService ts(e);
+ TestServiceChangeObserver o(&ts);
+ ts.set_observer(&o);
+
+ XorpTimer startup =3D e.new_oneoff_after_ms(TRANS_MS,
+ callback(&startup_test_service,
+ &ts));
+ XorpTimer shutdown =3D e.new_oneoff_after_ms(EXIT_MS,
+ callback(&shutdown_test_service,
+ &ts));
+
+ bool timed_out =3D false;
+ XorpTimer timeout =3D e.set_flag_after_ms(EXIT_MS + 3 * TRANS_MS, &t=
imed_out);
+
+ while (timed_out =3D=3D false && ts.status() !=3D SHUTDOWN) {
+ e.run();
+ }
+
+ if (timed_out) {
+ verbose_log("Test timed out.\n");
+ return -1;
+ }
+
+ if (o.changes_okay() =3D=3D false) {
+ verbose_log("Changes not okay.\n");
+ return -1;
+ }
+ return 0;
+}
+
+static void
+usage(const char* argv0)
+{
+ fprintf(stderr, "usage: %s [-v]\n", argv0);
+ fprintf(stderr, "A test program for XORP service classes\n");
+}
+
+int
+main(int argc, char* const* argv)
+{
+ //
+ // Initialize and start xlog
+ //
+ xlog_init(argv[0], NULL);
+ xlog_set_verbose(XLOG_VERBOSE_LOW); // Least verbose message=
s
+ // XXX: verbosity of the error messages temporary increased
+ xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH);
+ xlog_add_default_output();
+ xlog_start();
+
+ int ch;
+ while ((ch =3D getopt(argc, argv, "hv")) !=3D -1) {
+ switch (ch) {
+ case 'v':
+ set_verbose(true);
+ break;
+ case 'h':
+ case '?':
+ default:
+ usage(argv[0]);
+ xlog_stop();
+ xlog_exit();
+ return -1;
+ }
+ }
+ argc -=3D optind;
+ argv +=3D optind;
+
+ int r =3D 0;
+ XorpUnexpectedHandler x(xorp_unexpected_handler);
+ try {
+ r =3D run_test();
+ } catch (...) {
+ xorp_catch_standard_exceptions();
+ }
+ //
+ // Gracefully stop and exit xlog
+ //
+ xlog_stop();
+ xlog_exit();
+
+ return r;
+}
Index: libxorp/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/local/www/data/cvs/xorp/libxorp/Makefile.am,v
retrieving revision 1.13
diff -u -r1.13 Makefile.am
--- libxorp/Makefile.am 1 Aug 2003 02:11:48 -0000 1.13
+++ libxorp/Makefile.am 9 Oct 2003 07:04:56 -0000
@@ -20,14 +20,15 @@
TESTS +=3D test_mac
TESTS +=3D test_observers
TESTS +=3D test_ref_ptr
-TESTS +=3D test_ref_trie =
+TESTS +=3D test_ref_trie
+TESTS +=3D test_service
TESTS +=3D test_test_main
TESTS +=3D test_time_slice
TESTS +=3D test_timer
-TESTS +=3D test_timeval =
+TESTS +=3D test_timeval
TESTS +=3D test_trie
TESTS +=3D test_types
-TESTS +=3D test_vif =
+TESTS +=3D test_vif
=
# -- No-install Programs
noinst_PROGRAMS =3D test_asyncio
@@ -43,14 +44,15 @@
noinst_PROGRAMS +=3D test_mac
noinst_PROGRAMS +=3D test_observers
noinst_PROGRAMS +=3D test_ref_ptr
-noinst_PROGRAMS +=3D test_ref_trie =
+noinst_PROGRAMS +=3D test_ref_trie
+noinst_PROGRAMS +=3D test_service
noinst_PROGRAMS +=3D test_test_main
noinst_PROGRAMS +=3D test_time_slice
noinst_PROGRAMS +=3D test_timer
-noinst_PROGRAMS +=3D test_timeval =
+noinst_PROGRAMS +=3D test_timeval
noinst_PROGRAMS +=3D test_trie
noinst_PROGRAMS +=3D test_types
-noinst_PROGRAMS +=3D test_vif =
+noinst_PROGRAMS +=3D test_vif
=
# -- No-install Libraries
noinst_LIBRARIES =3D libxorp.a
@@ -73,6 +75,7 @@
test_observers_SOURCES =3D test_observers.cc
test_ref_ptr_SOURCES =3D test_ref_ptr.cc
test_ref_trie_SOURCES =3D test_ref_trie.cc
+test_service_SOURCES =3D test_service.cc
test_test_main_SOURCES =3D test_test_main.cc
test_time_slice_SOURCES =3D test_time_slice.cc
test_timer_SOURCES =3D test_timer.cc
@@ -111,6 +114,7 @@
libxorp_a_SOURCES +=3D old_trie.hh
libxorp_a_SOURCES +=3D ref_ptr.hh
libxorp_a_SOURCES +=3D selector.hh
+libxorp_a_SOURCES +=3D service.hh
libxorp_a_SOURCES +=3D time_slice.hh
libxorp_a_SOURCES +=3D timer.hh
libxorp_a_SOURCES +=3D timeval.hh
@@ -135,6 +139,7 @@
libxorp_a_SOURCES +=3D nexthop.cc
libxorp_a_SOURCES +=3D ref_ptr.cc
libxorp_a_SOURCES +=3D selector.cc
+libxorp_a_SOURCES +=3D service.cc
libxorp_a_SOURCES +=3D time_slice.cc
libxorp_a_SOURCES +=3D timer.cc
libxorp_a_SOURCES +=3D token.cc
Index: libxorp/Makefile.in
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/local/www/data/cvs/xorp/libxorp/Makefile.in,v
retrieving revision 1.22
diff -u -r1.22 Makefile.in
--- libxorp/Makefile.in 30 Sep 2003 20:28:50 -0000 1.22
+++ libxorp/Makefile.in 9 Oct 2003 07:04:56 -0000
@@ -95,10 +95,10 @@
bin_PROGRAMS =3D =
=
# -- Test Programs
-TESTS =3D test_asyncio test_callback test_config_param test_ipnet test_i=
pv4 test_ipv4net test_ipv6 test_ipv6net test_ipvx test_ipvxnet test_mac t=
est_observers test_ref_ptr test_ref_trie test_test_main test_time_slice =
test_timer test_timeval test_trie test_types test_vif =
+TESTS =3D test_asyncio test_callback test_config_param test_ipnet test_i=
pv4 test_ipv4net test_ipv6 test_ipv6net test_ipvx test_ipvxnet test_mac t=
est_observers test_ref_ptr test_ref_trie test_service test_test_main test=
_time_slice test_timer test_timeval test_trie test_types test_vif
=
# -- No-install Programs
-noinst_PROGRAMS =3D test_asyncio test_callback test_config_param test_ip=
net test_ipv4 test_ipv4net test_ipv6 test_ipv6net test_ipvx test_ipvxnet =
test_mac test_observers test_ref_ptr test_ref_trie test_test_main test_t=
ime_slice test_timer test_timeval test_trie test_types test_vif =
+noinst_PROGRAMS =3D test_asyncio test_callback test_config_param test_ip=
net test_ipv4 test_ipv4net test_ipv6 test_ipv6net test_ipvx test_ipvxnet =
test_mac test_observers test_ref_ptr test_ref_trie test_service test_test=
_main test_time_slice test_timer test_timeval test_trie test_types test_v=
if
=
# -- No-install Libraries
noinst_LIBRARIES =3D libxorp.a
@@ -121,6 +121,7 @@
test_observers_SOURCES =3D test_observers.cc
test_ref_ptr_SOURCES =3D test_ref_ptr.cc
test_ref_trie_SOURCES =3D test_ref_trie.cc
+test_service_SOURCES =3D test_service.cc
test_test_main_SOURCES =3D test_test_main.cc
test_time_slice_SOURCES =3D test_time_slice.cc
test_timer_SOURCES =3D test_timer.cc
@@ -130,7 +131,7 @@
test_vif_SOURCES =3D test_vif.cc
=
# -- Library Sources
-libxorp_a_SOURCES =3D libxorp_module.h debug.h ether_compat.h xlog.h xor=
p.h utility.h asnum.hh asyncio.hh buffer.hh c_format.hh callback.hh confi=
g_param.hh eventloop.hh exceptions.hh heap.hh ipnet.hh ipv4.hh ipv4net.hh=
ipv6.hh ipv6net.hh ipvx.hh ipvxnet.hh mac.hh nexthop.hh old_trie.hh ref_=
ptr.hh selector.hh time_slice.hh timer.hh timeval.hh token.hh transaction=
=2Ehh trie.hh utils.hh vif.hh debug.c xlog.c asyncio.cc c_format.cc event=
loop.cc exceptions.cc heap.cc ipv4.cc ipv6.cc ipvx.cc mac.cc nexthop.cc r=
ef_ptr.cc selector.cc time_slice.cc timer.cc token.cc transaction.cc vif.=
cc
+libxorp_a_SOURCES =3D libxorp_module.h debug.h ether_compat.h xlog.h xor=
p.h utility.h asnum.hh asyncio.hh buffer.hh c_format.hh callback.hh confi=
g_param.hh eventloop.hh exceptions.hh heap.hh ipnet.hh ipv4.hh ipv4net.hh=
ipv6.hh ipv6net.hh ipvx.hh ipvxnet.hh mac.hh nexthop.hh old_trie.hh ref_=
ptr.hh selector.hh service.hh time_slice.hh timer.hh timeval.hh token.hh =
transaction.hh trie.hh utils.hh vif.hh debug.c xlog.c asyncio.cc c_format=
=2Ecc eventloop.cc exceptions.cc heap.cc ipv4.cc ipv6.cc ipvx.cc mac.cc n=
exthop.cc ref_ptr.cc selector.cc service.cc time_slice.cc timer.cc token.=
cc transaction.cc vif.cc
=
BUILT_SOURCES =3D callback.hh
=
@@ -152,8 +153,9 @@
c_format.$(OBJEXT) eventloop.$(OBJEXT) exceptions.$(OBJEXT) \
heap.$(OBJEXT) ipv4.$(OBJEXT) ipv6.$(OBJEXT) ipvx.$(OBJEXT) \
mac.$(OBJEXT) nexthop.$(OBJEXT) ref_ptr.$(OBJEXT) \
- selector.$(OBJEXT) time_slice.$(OBJEXT) timer.$(OBJEXT) \
- token.$(OBJEXT) transaction.$(OBJEXT) vif.$(OBJEXT)
+ selector.$(OBJEXT) service.$(OBJEXT) time_slice.$(OBJEXT) \
+ timer.$(OBJEXT) token.$(OBJEXT) transaction.$(OBJEXT) \
+ vif.$(OBJEXT)
libxorp_a_OBJECTS =3D $(am_libxorp_a_OBJECTS)
bin_PROGRAMS =3D
noinst_PROGRAMS =3D test_asyncio$(EXEEXT) test_callback$(EXEEXT) \
@@ -161,10 +163,10 @@
test_ipv4$(EXEEXT) test_ipv4net$(EXEEXT) test_ipv6$(EXEEXT) \
test_ipv6net$(EXEEXT) test_ipvx$(EXEEXT) test_ipvxnet$(EXEEXT) \
test_mac$(EXEEXT) test_observers$(EXEEXT) test_ref_ptr$(EXEEXT) \
- test_ref_trie$(EXEEXT) test_test_main$(EXEEXT) \
- test_time_slice$(EXEEXT) test_timer$(EXEEXT) \
- test_timeval$(EXEEXT) test_trie$(EXEEXT) test_types$(EXEEXT) \
- test_vif$(EXEEXT)
+ test_ref_trie$(EXEEXT) test_service$(EXEEXT) \
+ test_test_main$(EXEEXT) test_time_slice$(EXEEXT) \
+ test_timer$(EXEEXT) test_timeval$(EXEEXT) test_trie$(EXEEXT) \
+ test_types$(EXEEXT) test_vif$(EXEEXT)
PROGRAMS =3D $(bin_PROGRAMS) $(noinst_PROGRAMS)
=
am_test_asyncio_OBJECTS =3D test_asyncio.$(OBJEXT)
@@ -237,6 +239,11 @@
test_ref_trie_LDADD =3D $(LDADD)
test_ref_trie_DEPENDENCIES =3D libxorp.a
test_ref_trie_LDFLAGS =3D
+am_test_service_OBJECTS =3D test_service.$(OBJEXT)
+test_service_OBJECTS =3D $(am_test_service_OBJECTS)
+test_service_LDADD =3D $(LDADD)
+test_service_DEPENDENCIES =3D libxorp.a
+test_service_LDFLAGS =3D
am_test_test_main_OBJECTS =3D test_test_main.$(OBJEXT)
test_test_main_OBJECTS =3D $(am_test_test_main_OBJECTS)
test_test_main_LDADD =3D $(LDADD)
@@ -285,7 +292,8 @@
@AMDEP_TRUE@ $(DEPDIR)/ipv4.Po $(DEPDIR)/ipv6.Po \
@AMDEP_TRUE@ $(DEPDIR)/ipvx.Po $(DEPDIR)/mac.Po \
@AMDEP_TRUE@ $(DEPDIR)/nexthop.Po $(DEPDIR)/ref_ptr.Po \
-@AMDEP_TRUE@ $(DEPDIR)/selector.Po $(DEPDIR)/test_asyncio.Po \
+@AMDEP_TRUE@ $(DEPDIR)/selector.Po $(DEPDIR)/service.Po \
+@AMDEP_TRUE@ $(DEPDIR)/test_asyncio.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_callback.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_config_param.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_ipnet.Po $(DEPDIR)/test_ipv4.Po \
@@ -295,6 +303,7 @@
@AMDEP_TRUE@ $(DEPDIR)/test_observers.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_ref_ptr.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_ref_trie.Po \
+@AMDEP_TRUE@ $(DEPDIR)/test_service.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_test_main.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_time_slice.Po \
@AMDEP_TRUE@ $(DEPDIR)/test_timer.Po $(DEPDIR)/test_timeval.Po \
@@ -321,12 +330,12 @@
$(test_ipv6net_SOURCES) $(test_ipvx_SOURCES) \
$(test_ipvxnet_SOURCES) $(test_mac_SOURCES) \
$(test_observers_SOURCES) $(test_ref_ptr_SOURCES) \
- $(test_ref_trie_SOURCES) $(test_test_main_SOURCES) \
- $(test_time_slice_SOURCES) $(test_timer_SOURCES) \
- $(test_timeval_SOURCES) $(test_trie_SOURCES) \
- $(test_types_SOURCES) $(test_vif_SOURCES)
+ $(test_ref_trie_SOURCES) $(test_service_SOURCES) \
+ $(test_test_main_SOURCES) $(test_time_slice_SOURCES) \
+ $(test_timer_SOURCES) $(test_timeval_SOURCES) \
+ $(test_trie_SOURCES) $(test_types_SOURCES) $(test_vif_SOURCES)
DIST_COMMON =3D README Makefile.am Makefile.in TODO
-SOURCES =3D $(libxorp_a_SOURCES) $(test_asyncio_SOURCES) $(test_callback=
_SOURCES) $(test_config_param_SOURCES) $(test_ipnet_SOURCES) $(test_ipv4_=
SOURCES) $(test_ipv4net_SOURCES) $(test_ipv6_SOURCES) $(test_ipv6net_SOUR=
CES) $(test_ipvx_SOURCES) $(test_ipvxnet_SOURCES) $(test_mac_SOURCES) $(t=
est_observers_SOURCES) $(test_ref_ptr_SOURCES) $(test_ref_trie_SOURCES) $=
(test_test_main_SOURCES) $(test_time_slice_SOURCES) $(test_timer_SOURCES)=
$(test_timeval_SOURCES) $(test_trie_SOURCES) $(test_types_SOURCES) $(tes=
t_vif_SOURCES)
+SOURCES =3D $(libxorp_a_SOURCES) $(test_asyncio_SOURCES) $(test_callback=
_SOURCES) $(test_config_param_SOURCES) $(test_ipnet_SOURCES) $(test_ipv4_=
SOURCES) $(test_ipv4net_SOURCES) $(test_ipv6_SOURCES) $(test_ipv6net_SOUR=
CES) $(test_ipvx_SOURCES) $(test_ipvxnet_SOURCES) $(test_mac_SOURCES) $(t=
est_observers_SOURCES) $(test_ref_ptr_SOURCES) $(test_ref_trie_SOURCES) $=
(test_service_SOURCES) $(test_test_main_SOURCES) $(test_time_slice_SOURCE=
S) $(test_timer_SOURCES) $(test_timeval_SOURCES) $(test_trie_SOURCES) $(t=
est_types_SOURCES) $(test_vif_SOURCES)
=
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -417,6 +426,9 @@
test_ref_trie$(EXEEXT): $(test_ref_trie_OBJECTS) $(test_ref_trie_DEPENDE=
NCIES) =
@rm -f test_ref_trie$(EXEEXT)
$(CXXLINK) $(test_ref_trie_LDFLAGS) $(test_ref_trie_OBJECTS) $(test_ref=
_trie_LDADD) $(LIBS)
+test_service$(EXEEXT): $(test_service_OBJECTS) $(test_service_DEPENDENCI=
ES) =
+ @rm -f test_service$(EXEEXT)
+ $(CXXLINK) $(test_service_LDFLAGS) $(test_service_OBJECTS) $(test_servi=
ce_LDADD) $(LIBS)
test_test_main$(EXEEXT): $(test_test_main_OBJECTS) $(test_test_main_DEPE=
NDENCIES) =
@rm -f test_test_main$(EXEEXT)
$(CXXLINK) $(test_test_main_LDFLAGS) $(test_test_main_OBJECTS) $(test_t=
est_main_LDADD) $(LIBS)
@@ -458,6 +470,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/nexthop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ref_ptr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/selector.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/service.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_asyncio.Po@am__quote=
@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_callback.Po@am__quot=
e@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_config_param.Po@am__=
quote@
@@ -472,6 +485,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_observers.Po@am__quo=
te@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_ref_ptr.Po@am__quote=
@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_ref_trie.Po@am__quot=
e@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_service.Po@am__quote=
@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_test_main.Po@am__quo=
te@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_time_slice.Po@am__qu=
ote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/test_timer.Po@am__quote@
--==_Exmh_16833281770--