--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_core.py Tue Jan 18 09:09:15 2011 -0800
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_core.py Wed Jan 19 10:51:11 2011 -0800
@@ -133,8 +133,6 @@
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::AttributeValue', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeValue>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h: ns3::SimpleRefCount<ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::CallbackImplBase', 'ns3::empty', 'ns3::DefaultDeleter<ns3::CallbackImplBase>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
- ## simple-ref-count.h: ns3::SimpleRefCount<ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> > [class]
- module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::FdReader', 'ns3::empty', 'ns3::DefaultDeleter<ns3::FdReader>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h: ns3::SimpleRefCount<ns3::FlowClassifier, ns3::empty, ns3::DefaultDeleter<ns3::FlowClassifier> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::FlowClassifier', 'ns3::empty', 'ns3::DefaultDeleter<ns3::FlowClassifier>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h: ns3::SimpleRefCount<ns3::FlowProbe, ns3::empty, ns3::DefaultDeleter<ns3::FlowProbe> > [class]
@@ -175,8 +173,6 @@
module.add_class('EnumChecker', parent=root_module['ns3::AttributeChecker'])
## enum.h: ns3::EnumValue [class]
module.add_class('EnumValue', parent=root_module['ns3::AttributeValue'])
- ## unix-fd-reader.h: ns3::FdReader [class]
- module.add_class('FdReader', parent=root_module['ns3::SimpleRefCount< ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> >'])
## integer.h: ns3::IntegerValue [class]
module.add_class('IntegerValue', parent=root_module['ns3::AttributeValue'])
## object-factory.h: ns3::ObjectFactoryChecker [class]
@@ -439,7 +435,6 @@
register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue'])
register_Ns3EnumChecker_methods(root_module, root_module['ns3::EnumChecker'])
register_Ns3EnumValue_methods(root_module, root_module['ns3::EnumValue'])
- register_Ns3FdReader_methods(root_module, root_module['ns3::FdReader'])
register_Ns3IntegerValue_methods(root_module, root_module['ns3::IntegerValue'])
register_Ns3ObjectFactoryChecker_methods(root_module, root_module['ns3::ObjectFactoryChecker'])
register_Ns3ObjectFactoryValue_methods(root_module, root_module['ns3::ObjectFactoryValue'])
@@ -2636,26 +2631,6 @@
[param('int', 'v')])
return
-def register_Ns3FdReader_methods(root_module, cls):
- ## unix-fd-reader.h: ns3::FdReader::FdReader(ns3::FdReader const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::FdReader const &', 'arg0')])
- ## unix-fd-reader.h: ns3::FdReader::FdReader() [constructor]
- cls.add_constructor([])
- ## unix-fd-reader.h: void ns3::FdReader::Start(int fd, ns3::Callback<void, unsigned char*, int, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> readCallback) [member function]
- cls.add_method('Start',
- 'void',
- [param('int', 'fd'), param('ns3::Callback< void, unsigned char *, int, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'readCallback')])
- ## unix-fd-reader.h: void ns3::FdReader::Stop() [member function]
- cls.add_method('Stop',
- 'void',
- [])
- ## unix-fd-reader.h: ns3::FdReader::Data ns3::FdReader::DoRead() [member function]
- cls.add_method('DoRead',
- 'ns3::FdReader::Data',
- [],
- is_pure_virtual=True, visibility='protected', is_virtual=True)
- return
-
def register_Ns3IntegerValue_methods(root_module, cls):
## integer.h: ns3::IntegerValue::IntegerValue() [constructor]
cls.add_constructor([])
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_simulator.py Tue Jan 18 09:09:15 2011 -0800
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_simulator.py Wed Jan 19 10:51:11 2011 -0800
@@ -43,6 +43,8 @@
module.add_class('EventKey', outer_class=root_module['ns3::Scheduler'])
## simple-ref-count.h: ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::EventImpl', 'ns3::empty', 'ns3::DefaultDeleter<ns3::EventImpl>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+ ## simple-ref-count.h: ns3::SimpleRefCount<ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> > [class]
+ module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::FdReader', 'ns3::empty', 'ns3::DefaultDeleter<ns3::FdReader>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simulator-impl.h: ns3::SimulatorImpl [class]
module.add_class('SimulatorImpl', parent=root_module['ns3::Object'])
## synchronizer.h: ns3::Synchronizer [class]
@@ -55,6 +57,8 @@
module.add_class('DefaultSimulatorImpl', parent=root_module['ns3::SimulatorImpl'])
## event-impl.h: ns3::EventImpl [class]
module.add_class('EventImpl', parent=root_module['ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >'])
+ ## unix-fd-reader.h: ns3::FdReader [class]
+ module.add_class('FdReader', parent=root_module['ns3::SimpleRefCount< ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> >'])
## heap-scheduler.h: ns3::HeapScheduler [class]
module.add_class('HeapScheduler', parent=root_module['ns3::Scheduler'])
## list-scheduler.h: ns3::ListScheduler [class]
@@ -189,6 +193,7 @@
register_Ns3CalendarScheduler_methods(root_module, root_module['ns3::CalendarScheduler'])
register_Ns3DefaultSimulatorImpl_methods(root_module, root_module['ns3::DefaultSimulatorImpl'])
register_Ns3EventImpl_methods(root_module, root_module['ns3::EventImpl'])
+ register_Ns3FdReader_methods(root_module, root_module['ns3::FdReader'])
register_Ns3HeapScheduler_methods(root_module, root_module['ns3::HeapScheduler'])
register_Ns3ListScheduler_methods(root_module, root_module['ns3::ListScheduler'])
register_Ns3MapScheduler_methods(root_module, root_module['ns3::MapScheduler'])
@@ -1274,6 +1279,26 @@
is_pure_virtual=True, visibility='protected', is_virtual=True)
return
+def register_Ns3FdReader_methods(root_module, cls):
+ ## unix-fd-reader.h: ns3::FdReader::FdReader(ns3::FdReader const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::FdReader const &', 'arg0')])
+ ## unix-fd-reader.h: ns3::FdReader::FdReader() [constructor]
+ cls.add_constructor([])
+ ## unix-fd-reader.h: void ns3::FdReader::Start(int fd, ns3::Callback<void, unsigned char*, int, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> readCallback) [member function]
+ cls.add_method('Start',
+ 'void',
+ [param('int', 'fd'), param('ns3::Callback< void, unsigned char *, int, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'readCallback')])
+ ## unix-fd-reader.h: void ns3::FdReader::Stop() [member function]
+ cls.add_method('Stop',
+ 'void',
+ [])
+ ## unix-fd-reader.h: ns3::FdReader::Data ns3::FdReader::DoRead() [member function]
+ cls.add_method('DoRead',
+ 'ns3::FdReader::Data',
+ [],
+ is_pure_virtual=True, visibility='protected', is_virtual=True)
+ return
+
def register_Ns3HeapScheduler_methods(root_module, cls):
## heap-scheduler.h: ns3::HeapScheduler::HeapScheduler(ns3::HeapScheduler const & arg0) [copy constructor]
cls.add_constructor([param('ns3::HeapScheduler const &', 'arg0')])
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_core.py Tue Jan 18 09:09:15 2011 -0800
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_core.py Wed Jan 19 10:51:11 2011 -0800
@@ -133,8 +133,6 @@
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::AttributeValue', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeValue>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h: ns3::SimpleRefCount<ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::CallbackImplBase', 'ns3::empty', 'ns3::DefaultDeleter<ns3::CallbackImplBase>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
- ## simple-ref-count.h: ns3::SimpleRefCount<ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> > [class]
- module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::FdReader', 'ns3::empty', 'ns3::DefaultDeleter<ns3::FdReader>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h: ns3::SimpleRefCount<ns3::FlowClassifier, ns3::empty, ns3::DefaultDeleter<ns3::FlowClassifier> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::FlowClassifier', 'ns3::empty', 'ns3::DefaultDeleter<ns3::FlowClassifier>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h: ns3::SimpleRefCount<ns3::FlowProbe, ns3::empty, ns3::DefaultDeleter<ns3::FlowProbe> > [class]
@@ -175,8 +173,6 @@
module.add_class('EnumChecker', parent=root_module['ns3::AttributeChecker'])
## enum.h: ns3::EnumValue [class]
module.add_class('EnumValue', parent=root_module['ns3::AttributeValue'])
- ## unix-fd-reader.h: ns3::FdReader [class]
- module.add_class('FdReader', parent=root_module['ns3::SimpleRefCount< ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> >'])
## integer.h: ns3::IntegerValue [class]
module.add_class('IntegerValue', parent=root_module['ns3::AttributeValue'])
## object-factory.h: ns3::ObjectFactoryChecker [class]
@@ -439,7 +435,6 @@
register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue'])
register_Ns3EnumChecker_methods(root_module, root_module['ns3::EnumChecker'])
register_Ns3EnumValue_methods(root_module, root_module['ns3::EnumValue'])
- register_Ns3FdReader_methods(root_module, root_module['ns3::FdReader'])
register_Ns3IntegerValue_methods(root_module, root_module['ns3::IntegerValue'])
register_Ns3ObjectFactoryChecker_methods(root_module, root_module['ns3::ObjectFactoryChecker'])
register_Ns3ObjectFactoryValue_methods(root_module, root_module['ns3::ObjectFactoryValue'])
@@ -2636,26 +2631,6 @@
[param('int', 'v')])
return
-def register_Ns3FdReader_methods(root_module, cls):
- ## unix-fd-reader.h: ns3::FdReader::FdReader(ns3::FdReader const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::FdReader const &', 'arg0')])
- ## unix-fd-reader.h: ns3::FdReader::FdReader() [constructor]
- cls.add_constructor([])
- ## unix-fd-reader.h: void ns3::FdReader::Start(int fd, ns3::Callback<void, unsigned char*, long, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> readCallback) [member function]
- cls.add_method('Start',
- 'void',
- [param('int', 'fd'), param('ns3::Callback< void, unsigned char *, long, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'readCallback')])
- ## unix-fd-reader.h: void ns3::FdReader::Stop() [member function]
- cls.add_method('Stop',
- 'void',
- [])
- ## unix-fd-reader.h: ns3::FdReader::Data ns3::FdReader::DoRead() [member function]
- cls.add_method('DoRead',
- 'ns3::FdReader::Data',
- [],
- is_pure_virtual=True, visibility='protected', is_virtual=True)
- return
-
def register_Ns3IntegerValue_methods(root_module, cls):
## integer.h: ns3::IntegerValue::IntegerValue() [constructor]
cls.add_constructor([])
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_simulator.py Tue Jan 18 09:09:15 2011 -0800
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_simulator.py Wed Jan 19 10:51:11 2011 -0800
@@ -43,6 +43,8 @@
module.add_class('EventKey', outer_class=root_module['ns3::Scheduler'])
## simple-ref-count.h: ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::EventImpl', 'ns3::empty', 'ns3::DefaultDeleter<ns3::EventImpl>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+ ## simple-ref-count.h: ns3::SimpleRefCount<ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> > [class]
+ module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::FdReader', 'ns3::empty', 'ns3::DefaultDeleter<ns3::FdReader>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simulator-impl.h: ns3::SimulatorImpl [class]
module.add_class('SimulatorImpl', parent=root_module['ns3::Object'])
## synchronizer.h: ns3::Synchronizer [class]
@@ -55,6 +57,8 @@
module.add_class('DefaultSimulatorImpl', parent=root_module['ns3::SimulatorImpl'])
## event-impl.h: ns3::EventImpl [class]
module.add_class('EventImpl', parent=root_module['ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >'])
+ ## unix-fd-reader.h: ns3::FdReader [class]
+ module.add_class('FdReader', parent=root_module['ns3::SimpleRefCount< ns3::FdReader, ns3::empty, ns3::DefaultDeleter<ns3::FdReader> >'])
## heap-scheduler.h: ns3::HeapScheduler [class]
module.add_class('HeapScheduler', parent=root_module['ns3::Scheduler'])
## list-scheduler.h: ns3::ListScheduler [class]
@@ -189,6 +193,7 @@
register_Ns3CalendarScheduler_methods(root_module, root_module['ns3::CalendarScheduler'])
register_Ns3DefaultSimulatorImpl_methods(root_module, root_module['ns3::DefaultSimulatorImpl'])
register_Ns3EventImpl_methods(root_module, root_module['ns3::EventImpl'])
+ register_Ns3FdReader_methods(root_module, root_module['ns3::FdReader'])
register_Ns3HeapScheduler_methods(root_module, root_module['ns3::HeapScheduler'])
register_Ns3ListScheduler_methods(root_module, root_module['ns3::ListScheduler'])
register_Ns3MapScheduler_methods(root_module, root_module['ns3::MapScheduler'])
@@ -1274,6 +1279,26 @@
is_pure_virtual=True, visibility='protected', is_virtual=True)
return
+def register_Ns3FdReader_methods(root_module, cls):
+ ## unix-fd-reader.h: ns3::FdReader::FdReader(ns3::FdReader const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::FdReader const &', 'arg0')])
+ ## unix-fd-reader.h: ns3::FdReader::FdReader() [constructor]
+ cls.add_constructor([])
+ ## unix-fd-reader.h: void ns3::FdReader::Start(int fd, ns3::Callback<void, unsigned char*, long, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> readCallback) [member function]
+ cls.add_method('Start',
+ 'void',
+ [param('int', 'fd'), param('ns3::Callback< void, unsigned char *, long, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'readCallback')])
+ ## unix-fd-reader.h: void ns3::FdReader::Stop() [member function]
+ cls.add_method('Stop',
+ 'void',
+ [])
+ ## unix-fd-reader.h: ns3::FdReader::Data ns3::FdReader::DoRead() [member function]
+ cls.add_method('DoRead',
+ 'ns3::FdReader::Data',
+ [],
+ is_pure_virtual=True, visibility='protected', is_virtual=True)
+ return
+
def register_Ns3HeapScheduler_methods(root_module, cls):
## heap-scheduler.h: ns3::HeapScheduler::HeapScheduler(ns3::HeapScheduler const & arg0) [copy constructor]
cls.add_constructor([param('ns3::HeapScheduler const &', 'arg0')])
--- a/samples/wscript Tue Jan 18 09:09:15 2011 -0800
+++ b/samples/wscript Wed Jan 19 10:51:11 2011 -0800
@@ -11,7 +11,7 @@
obj = bld.create_ns3_program('main-callback', ['core'])
obj.source = 'main-callback.cc'
- obj = bld.create_ns3_program('sample-simulator', ['core'])
+ obj = bld.create_ns3_program('sample-simulator', ['core', 'simulator'])
obj.source = 'sample-simulator.cc'
obj = bld.create_ns3_program('main-ptr', ['core'] )
--- a/src/core/unix-fd-reader.cc Tue Jan 18 09:09:15 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2010 The Boeing Company
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Tom Goff <thomas.goff@boeing.com>
- */
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "ns3/log.h"
-#include "ns3/fatal-error.h"
-#include "ns3/simple-ref-count.h"
-#include "ns3/system-thread.h"
-#include "ns3/simulator.h"
-
-#include "unix-fd-reader.h"
-
-NS_LOG_COMPONENT_DEFINE ("FdReader");
-
-namespace ns3 {
-
-FdReader::FdReader ()
- : m_fd (-1), m_readCallback (0), m_readThread (0), m_stop (false),
- m_destroyEvent ()
-{
- m_evpipe[0] = -1;
- m_evpipe[1] = -1;
-}
-
-FdReader::~FdReader ()
-{
- Stop ();
-}
-
-void FdReader::Start (int fd, Callback<void, uint8_t *, ssize_t> readCallback)
-{
- int tmp;
-
- NS_ASSERT_MSG (m_readThread == 0, "read thread already exists");
-
- // create a pipe for inter-thread event notification
- tmp = pipe (m_evpipe);
- if (tmp == -1)
- {
- NS_FATAL_ERROR ("pipe() failed: " << strerror (errno));
- }
-
- // make the read end non-blocking
- tmp = fcntl(m_evpipe[0], F_GETFL);
- if (tmp == -1)
- {
- NS_FATAL_ERROR ("fcntl() failed: " << strerror (errno));
- }
- if (fcntl(m_evpipe[0], F_SETFL, tmp | O_NONBLOCK) == -1)
- {
- NS_FATAL_ERROR ("fcntl() failed: " << strerror (errno));
- }
-
- m_fd = fd;
- m_readCallback = readCallback;
-
- //
- // We're going to spin up a thread soon, so we need to make sure we have
- // a way to tear down that thread when the simulation stops. Do this by
- // scheduling a "destroy time" method to make sure the thread exits before
- // proceeding.
- //
- if (! m_destroyEvent.IsRunning ())
- {
- // hold a reference to ensure that this object is not
- // deallocated before the destroy-time event fires
- this->Ref ();
- m_destroyEvent =
- Simulator::ScheduleDestroy (&FdReader::DestroyEvent, this);
- }
-
- //
- // Now spin up a thread to read from the fd
- //
- NS_LOG_LOGIC ("Spinning up read thread");
-
- m_readThread = Create<SystemThread> (MakeCallback (&FdReader::Run, this));
- m_readThread->Start ();
-}
-
-void FdReader::DestroyEvent (void)
-{
- Stop ();
- this->Unref ();
-}
-
-void FdReader::Stop (void)
-{
- m_stop = true;
-
- // signal the read thread and close the write end of the event pipe
- if (m_evpipe[1] != -1)
- {
- char zero = 0;
- ssize_t len = write (m_evpipe[1], &zero, sizeof (zero));
- if (len != sizeof (zero))
- NS_LOG_WARN ("incomplete write(): " << strerror (errno));
- close (m_evpipe[1]);
- m_evpipe[1] = -1;
- }
-
- // join the read thread
- if (m_readThread != 0)
- {
- m_readThread->Join ();
- m_readThread = 0;
- }
-
- // close the read end of the event pipe
- if (m_evpipe[0] != -1)
- {
- close (m_evpipe[0]);
- m_evpipe[0] = -1;
- }
-
- // reset everything else
- m_fd = -1;
- m_readCallback.Nullify ();
- m_stop = false;
-}
-
-// This runs in a separate thread
-void FdReader::Run (void)
-{
- int nfds;
- fd_set rfds;
-
- nfds = (m_fd > m_evpipe[0] ? m_fd : m_evpipe[0]) + 1;
-
- FD_ZERO (&rfds);
- FD_SET (m_fd, &rfds);
- FD_SET (m_evpipe[0], &rfds);
-
- for (;;)
- {
- int r;
- fd_set readfds = rfds;
-
- r = select (nfds, &readfds, NULL, NULL, NULL);
- if (r == -1 && errno != EINTR)
- {
- NS_FATAL_ERROR ("select() failed: " << strerror (errno));
- }
-
- if (FD_ISSET (m_evpipe[0], &readfds))
- {
- // drain the event pipe
- ssize_t len;
- for (;;)
- {
- char buf[1024];
- len = read (m_evpipe[0], buf, sizeof (buf));
- if (len == 0)
- {
- NS_FATAL_ERROR ("event pipe closed");
- }
- if (len < 0)
- {
- break;
- }
- }
-
- if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
- {
- NS_LOG_WARN ("read() failed: " << strerror (errno));
- break;
- }
- }
-
- if (m_stop)
- {
- // this thread is done
- break;
- }
-
- if (FD_ISSET (m_fd, &readfds))
- {
- struct FdReader::Data data = DoRead ();
- // reading stops when m_len is zero
- if (data.m_len == 0)
- {
- break;
- }
- // the callback is only called when m_len is positive (data
- // is ignored if m_len is negative)
- else if (data.m_len > 0)
- {
- m_readCallback (data.m_buf, data.m_len);
- }
- }
- }
-}
-
-} // namespace ns3
--- a/src/core/unix-fd-reader.h Tue Jan 18 09:09:15 2011 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2010 The Boeing Company
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Tom Goff <thomas.goff@boeing.com>
- */
-
-#ifndef UNIX_FD_READER_H
-#define UNIX_FD_READER_H
-
-#include <stdint.h>
-
-#include "ns3/callback.h"
-#include "ns3/system-thread.h"
-#include "ns3/event-id.h"
-
-namespace ns3 {
-
-/**
- * \brief A class that asynchronously reads from a file descriptor.
- *
- * This class can be used to start a system thread that reads from a
- * given file descriptor and invokes a given callback when data is
- * received. This class handles thread management automatically but
- * the \p DoRead() method must be implemented by a subclass.
- */
-class FdReader : public SimpleRefCount<FdReader>
-{
-public:
- FdReader();
- virtual ~FdReader();
-
- /**
- * Start a new read thread.
- *
- * \param fd A valid file descriptor open for reading.
- *
- * \param readCallback A callback to invoke when new data is
- * available.
- */
- void Start (int fd, Callback<void, uint8_t *, ssize_t> readCallback);
-
- /**
- * Stop the read thread and reset internal state. This does not
- * close the file descriptor used for reading.
- */
- void Stop (void);
-
-protected:
-
- /**
- * \internal
- * \brief A structure representing data read.
- */
- struct Data
- {
- Data () : m_buf (0), m_len (0) {}
- Data (uint8_t *buf, ssize_t len) : m_buf (buf), m_len (len) {}
- uint8_t *m_buf;
- ssize_t m_len;
- };
-
- /**
- * \internal
- * \brief The read implementation.
- *
- * The value of \p m_len returned controls further processing. The
- * callback function is only invoked when \p m_len is positive; any
- * data read is not processed when \p m_len is negative; reading
- * stops when \p m_len is zero.
- *
- * The management of memory associated with \p m_buf must be
- * compatible with the read callback.
- *
- * \return A structure representing what was read.
- */
- virtual FdReader::Data DoRead (void) = 0;
-
- /**
- * \internal
- * \brief The file descriptor to read from.
- */
- int m_fd;
-
-private:
-
- void Run (void);
- void DestroyEvent (void);
-
- Callback<void, uint8_t *, ssize_t> m_readCallback;
- Ptr<SystemThread> m_readThread;
- int m_evpipe[2]; // pipe used to signal events between threads
- bool m_stop; // true means the read thread should stop
- EventId m_destroyEvent;
-};
-
-} // namespace ns3
-
-#endif // UNIX_FD_READER_H
--- a/src/core/wscript Tue Jan 18 09:09:15 2011 -0800
+++ b/src/core/wscript Wed Jan 19 10:51:11 2011 -0800
@@ -146,14 +146,12 @@
'unix-system-thread.cc',
'unix-system-mutex.cc',
'unix-system-condition.cc',
- 'unix-fd-reader.cc',
])
core.uselib = 'PTHREAD'
headers.source.extend([
'system-mutex.h',
'system-thread.h',
'system-condition.h',
- 'unix-fd-reader.h',
])
if bld.env['ENABLE_GSL']:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/unix-fd-reader.cc Wed Jan 19 10:51:11 2011 -0800
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (c) 2010 The Boeing Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Tom Goff <thomas.goff@boeing.com>
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "ns3/log.h"
+#include "ns3/fatal-error.h"
+#include "ns3/simple-ref-count.h"
+#include "ns3/system-thread.h"
+#include "ns3/simulator.h"
+
+#include "unix-fd-reader.h"
+
+NS_LOG_COMPONENT_DEFINE ("FdReader");
+
+namespace ns3 {
+
+FdReader::FdReader ()
+ : m_fd (-1), m_readCallback (0), m_readThread (0), m_stop (false),
+ m_destroyEvent ()
+{
+ m_evpipe[0] = -1;
+ m_evpipe[1] = -1;
+}
+
+FdReader::~FdReader ()
+{
+ Stop ();
+}
+
+void FdReader::Start (int fd, Callback<void, uint8_t *, ssize_t> readCallback)
+{
+ int tmp;
+
+ NS_ASSERT_MSG (m_readThread == 0, "read thread already exists");
+
+ // create a pipe for inter-thread event notification
+ tmp = pipe (m_evpipe);
+ if (tmp == -1)
+ {
+ NS_FATAL_ERROR ("pipe() failed: " << strerror (errno));
+ }
+
+ // make the read end non-blocking
+ tmp = fcntl(m_evpipe[0], F_GETFL);
+ if (tmp == -1)
+ {
+ NS_FATAL_ERROR ("fcntl() failed: " << strerror (errno));
+ }
+ if (fcntl(m_evpipe[0], F_SETFL, tmp | O_NONBLOCK) == -1)
+ {
+ NS_FATAL_ERROR ("fcntl() failed: " << strerror (errno));
+ }
+
+ m_fd = fd;
+ m_readCallback = readCallback;
+
+ //
+ // We're going to spin up a thread soon, so we need to make sure we have
+ // a way to tear down that thread when the simulation stops. Do this by
+ // scheduling a "destroy time" method to make sure the thread exits before
+ // proceeding.
+ //
+ if (! m_destroyEvent.IsRunning ())
+ {
+ // hold a reference to ensure that this object is not
+ // deallocated before the destroy-time event fires
+ this->Ref ();
+ m_destroyEvent =
+ Simulator::ScheduleDestroy (&FdReader::DestroyEvent, this);
+ }
+
+ //
+ // Now spin up a thread to read from the fd
+ //
+ NS_LOG_LOGIC ("Spinning up read thread");
+
+ m_readThread = Create<SystemThread> (MakeCallback (&FdReader::Run, this));
+ m_readThread->Start ();
+}
+
+void FdReader::DestroyEvent (void)
+{
+ Stop ();
+ this->Unref ();
+}
+
+void FdReader::Stop (void)
+{
+ m_stop = true;
+
+ // signal the read thread and close the write end of the event pipe
+ if (m_evpipe[1] != -1)
+ {
+ char zero = 0;
+ ssize_t len = write (m_evpipe[1], &zero, sizeof (zero));
+ if (len != sizeof (zero))
+ NS_LOG_WARN ("incomplete write(): " << strerror (errno));
+ close (m_evpipe[1]);
+ m_evpipe[1] = -1;
+ }
+
+ // join the read thread
+ if (m_readThread != 0)
+ {
+ m_readThread->Join ();
+ m_readThread = 0;
+ }
+
+ // close the read end of the event pipe
+ if (m_evpipe[0] != -1)
+ {
+ close (m_evpipe[0]);
+ m_evpipe[0] = -1;
+ }
+
+ // reset everything else
+ m_fd = -1;
+ m_readCallback.Nullify ();
+ m_stop = false;
+}
+
+// This runs in a separate thread
+void FdReader::Run (void)
+{
+ int nfds;
+ fd_set rfds;
+
+ nfds = (m_fd > m_evpipe[0] ? m_fd : m_evpipe[0]) + 1;
+
+ FD_ZERO (&rfds);
+ FD_SET (m_fd, &rfds);
+ FD_SET (m_evpipe[0], &rfds);
+
+ for (;;)
+ {
+ int r;
+ fd_set readfds = rfds;
+
+ r = select (nfds, &readfds, NULL, NULL, NULL);
+ if (r == -1 && errno != EINTR)
+ {
+ NS_FATAL_ERROR ("select() failed: " << strerror (errno));
+ }
+
+ if (FD_ISSET (m_evpipe[0], &readfds))
+ {
+ // drain the event pipe
+ ssize_t len;
+ for (;;)
+ {
+ char buf[1024];
+ len = read (m_evpipe[0], buf, sizeof (buf));
+ if (len == 0)
+ {
+ NS_FATAL_ERROR ("event pipe closed");
+ }
+ if (len < 0)
+ {
+ break;
+ }
+ }
+
+ if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
+ {
+ NS_LOG_WARN ("read() failed: " << strerror (errno));
+ break;
+ }
+ }
+
+ if (m_stop)
+ {
+ // this thread is done
+ break;
+ }
+
+ if (FD_ISSET (m_fd, &readfds))
+ {
+ struct FdReader::Data data = DoRead ();
+ // reading stops when m_len is zero
+ if (data.m_len == 0)
+ {
+ break;
+ }
+ // the callback is only called when m_len is positive (data
+ // is ignored if m_len is negative)
+ else if (data.m_len > 0)
+ {
+ m_readCallback (data.m_buf, data.m_len);
+ }
+ }
+ }
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/unix-fd-reader.h Wed Jan 19 10:51:11 2011 -0800
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (c) 2010 The Boeing Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Tom Goff <thomas.goff@boeing.com>
+ */
+
+#ifndef UNIX_FD_READER_H
+#define UNIX_FD_READER_H
+
+#include <stdint.h>
+
+#include "ns3/callback.h"
+#include "ns3/system-thread.h"
+#include "ns3/event-id.h"
+
+namespace ns3 {
+
+/**
+ * \brief A class that asynchronously reads from a file descriptor.
+ *
+ * This class can be used to start a system thread that reads from a
+ * given file descriptor and invokes a given callback when data is
+ * received. This class handles thread management automatically but
+ * the \p DoRead() method must be implemented by a subclass.
+ */
+class FdReader : public SimpleRefCount<FdReader>
+{
+public:
+ FdReader();
+ virtual ~FdReader();
+
+ /**
+ * Start a new read thread.
+ *
+ * \param fd A valid file descriptor open for reading.
+ *
+ * \param readCallback A callback to invoke when new data is
+ * available.
+ */
+ void Start (int fd, Callback<void, uint8_t *, ssize_t> readCallback);
+
+ /**
+ * Stop the read thread and reset internal state. This does not
+ * close the file descriptor used for reading.
+ */
+ void Stop (void);
+
+protected:
+
+ /**
+ * \internal
+ * \brief A structure representing data read.
+ */
+ struct Data
+ {
+ Data () : m_buf (0), m_len (0) {}
+ Data (uint8_t *buf, ssize_t len) : m_buf (buf), m_len (len) {}
+ uint8_t *m_buf;
+ ssize_t m_len;
+ };
+
+ /**
+ * \internal
+ * \brief The read implementation.
+ *
+ * The value of \p m_len returned controls further processing. The
+ * callback function is only invoked when \p m_len is positive; any
+ * data read is not processed when \p m_len is negative; reading
+ * stops when \p m_len is zero.
+ *
+ * The management of memory associated with \p m_buf must be
+ * compatible with the read callback.
+ *
+ * \return A structure representing what was read.
+ */
+ virtual FdReader::Data DoRead (void) = 0;
+
+ /**
+ * \internal
+ * \brief The file descriptor to read from.
+ */
+ int m_fd;
+
+private:
+
+ void Run (void);
+ void DestroyEvent (void);
+
+ Callback<void, uint8_t *, ssize_t> m_readCallback;
+ Ptr<SystemThread> m_readThread;
+ int m_evpipe[2]; // pipe used to signal events between threads
+ bool m_stop; // true means the read thread should stop
+ EventId m_destroyEvent;
+};
+
+} // namespace ns3
+
+#endif // UNIX_FD_READER_H
--- a/src/simulator/wscript Tue Jan 18 09:09:15 2011 -0800
+++ b/src/simulator/wscript Wed Jan 19 10:51:11 2011 -0800
@@ -126,4 +126,12 @@
])
sim.uselib = 'RT'
+ if env['ENABLE_THREADING']:
+ sim.source.extend([
+ 'unix-fd-reader.cc',
+ ])
+ sim.uselib = sim.uselib + ' PTHREAD'
+ headers.source.extend([
+ 'unix-fd-reader.h',
+ ])