int ThreadPerConnectionSendTask::add_request(SendStrategyOpType op, TransportQueueElement* element) { DBG_ENTRY("ThreadPerConnectionSendTask", "add"); ACE_Auto_Ptr<SendRequest> req(new SendRequest); req->op_ = op; req->element_ = element; int result = -1; { // guard scope GuardType guard(this->lock_); if (this->shutdown_initiated_) { return -1; } result = this->queue_.put(req.get()); if (result == 0) { this->work_available_.signal(); req.release(); } else { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: ThreadPerConnectionSendTask::add %p\n"), ACE_TEXT("put"))); } } return result; }
int ThreadPerConnectionSendTask::close(u_long flag) { DBG_ENTRY("ThreadPerConnectionSendTask","close"); if (flag == 0) { return 0; } { GuardType guard(this->lock_); if (this->shutdown_initiated_) { return 0; } // Set the shutdown flag to true. this->shutdown_initiated_ = true; this->work_available_.signal(); } if (this->opened_ && !ACE_OS::thr_equal(this->thr_id_, ACE_OS::thr_self())) { this->wait(); } return 0; }
void PubDriver::init() { DBG_ENTRY("PubDriver","init"); OpenDDS::DCPS::TransportInst_rch inst; if (shmem_) { VDBG((LM_DEBUG, "(%P|%t) DBG: Create a new ShmemInst object.\n")); inst = TheTransportRegistry->create_inst("shmem1", "shmem"); } else { VDBG((LM_DEBUG, "(%P|%t) DBG: Create a new TcpInst object.\n")); inst = TheTransportRegistry->create_inst("tcp1", "tcp"); OpenDDS::DCPS::TcpInst_rch tcp_inst = OpenDDS::DCPS::dynamic_rchandle_cast<OpenDDS::DCPS::TcpInst>(inst); VDBG((LM_DEBUG, "(%P|%t) DBG: " "Set the inst->local_address_ to our (local) pub_addr_.\n")); tcp_inst->local_address(ACE_TEXT_ALWAYS_CHAR(this->pub_addr_str_.c_str())); } OpenDDS::DCPS::TransportConfig_rch cfg = TheTransportRegistry->create_config("cfg"); cfg->instances_.push_back(inst); TheTransportRegistry->global_config(cfg); VDBG((LM_DEBUG, "(%P|%t) DBG: " "The Transport has been successfully configured.\n")); }
SimpleDataWriter::SimpleDataWriter(const OpenDDS::DCPS::RepoId& pub_id) : pub_id_(pub_id) , num_messages_sent_(0) , num_messages_delivered_(0) { DBG_ENTRY("SimpleDataWriter","SimpleDataWriter"); }
void SimpleDataWriter::init(TAO::DCPS::RepoId pub_id) { DBG_ENTRY("SimpleDataWriter","init"); this->pub_id_ = pub_id; }
int OpenDDS::DCPS::ThreadPerConnectionSendTask::open(void*) { DBG_ENTRY("ThreadPerConnectionSendTask","open"); GuardType guard(this->lock_); // We can assume that we are in the proper state to handle this open() // call as long as we haven't been open()'ed before. if (this->opened_) { ACE_ERROR_RETURN((LM_ERROR, "(%P|%t) ThreadPerConnectionSendTask failed to open. " "Task has previously been open()'ed.\n"), -1); } // Activate this task object with one worker thread. if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0) { // Assumes that when activate returns non-zero return code that // no threads were activated. ACE_ERROR_RETURN((LM_ERROR, "(%P|%t) ThreadPerConnectionSendTask failed to activate " "the worker threads.\n"), -1); } // Now we have past the point where we can say we've been open()'ed before. this->opened_ = true; return 0; }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { DBG_ENTRY("pub_main.cpp","main"); ACE_LOG_MSG->priority_mask(LM_TRACE | LM_DEBUG | LM_INFO | LM_NOTICE | LM_WARNING | LM_ERROR | LM_CRITICAL | LM_ALERT | LM_EMERGENCY, ACE_Log_Msg::PROCESS); for (int i = 1; i < argc; ++i) { if (0 == ACE_OS::strcasecmp(argv[i], ACE_TEXT("-q"))) { const u_long mask = ACE_LOG_MSG->priority_mask(ACE_Log_Msg::PROCESS); ACE_LOG_MSG->priority_mask(mask & ~LM_DEBUG, ACE_Log_Msg::PROCESS); } } VDBG((LM_DEBUG, "(%P|%t) DBG: " "Create the PubDriver object.\n")); PubDriver driver; try { VDBG((LM_DEBUG, "(%P|%t) DBG: " "Tell the PubDriver object to run(argc,argv).\n")); driver.run(argc, argv); VDBG((LM_DEBUG, "(%P|%t) DBG: " "PubDriver object has completed running. " "Exit process with success code (0).\n")); return 0; } catch (const TestException&) { ACE_ERROR((LM_ERROR, "(%P|%t) PubDriver TestException.\n")); } catch (...) { ACE_ERROR((LM_ERROR, "(%P|%t) PubDriver unknown (...) exception.\n")); } VDBG((LM_DEBUG, "(%P|%t) DBG: " "PubDriver object has completed running due to an exception. " "Exit process with failure code (1).\n")); return 1; }
void SimpleDataWriter::transport_lost() { DBG_ENTRY("SimpleDataWriter","transport_lost"); ACE_DEBUG((LM_DEBUG, "(%P|%t) The transport has been lost.\n")); }
SubDriver::SubDriver() : pub_id_(OpenDDS::DCPS::GuidBuilder::create()) , sub_id_(OpenDDS::DCPS::GuidBuilder::create()) , reader_(sub_id_) , num_msgs_(1) , shmem_(false) { DBG_ENTRY("SubDriver","SubDriver"); }
void SimpleSubscriber::transport_detached_i() { DBG_ENTRY("SimpleSubscriber","transport_detached_i"); ACE_DEBUG((LM_DEBUG, "(%P|%t) Transport has detached from SimpleSubscriber.\n")); this->reader_.transport_lost(); }
PubDriver::PubDriver() : pub_id_(OpenDDS::DCPS::GuidBuilder::create()) , sub_id_(OpenDDS::DCPS::GuidBuilder::create()) , writer_(pub_id_) , num_msgs_(1) , msg_size_(0) , shmem_(false) { DBG_ENTRY("PubDriver","PubDriver"); }
int ThreadPerConnectionSendTask::open(void*) { DBG_ENTRY("ThreadPerConnectionSendTask", "open"); GuardType guard(this->lock_); // We can assume that we are in the proper state to handle this open() // call as long as we haven't been open()'ed before. if (this->opened_) { ACE_ERROR_RETURN((LM_ERROR, "(%P|%t) ThreadPerConnectionSendTask failed to open. " "Task has previously been open()'ed.\n"), -1); } DirectPriorityMapper mapper(this->link_->transport_priority()); int priority = mapper.thread_priority(); long flags = THR_NEW_LWP | THR_JOINABLE ;//|THR_SCOPE_PROCESS | THR_SCOPE_THREAD; int policy = TheServiceParticipant->scheduler(); if (policy >= 0) { flags |= policy; } else { flags |= THR_INHERIT_SCHED; } if (DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) ThreadPerConnectionSendTask::open(): ") ACE_TEXT("activating thread with flags 0x%08.8x ") ACE_TEXT("and priority %d.\n"), flags, priority)); } // Activate this task object with one worker thread. if (this->activate(flags, 1, 0, priority) != 0) { // Assumes that when activate returns non-zero return code that // no threads were activated. ACE_ERROR_RETURN((LM_ERROR, "(%P|%t) ThreadPerConnectionSendTask failed to activate " "the worker threads.\n"), -1); } // Now we have past the point where we can say we've been open()'ed before. this->opened_ = true; return 0; }
int OpenDDS::DCPS::ThreadPerConnectionSendTask::remove_sample(TransportSendElement& element) { DBG_ENTRY("ThreadPerConnectionSendTask","remove_sample"); GuardType guard(this->lock_); ThreadPerConRemoveVisitor vistor(element.msg()); // Let it visit our elems_ collection as a "replace" visitor. this->queue_.accept_visitor(vistor); return vistor.status(); }
RemoveResult ThreadPerConnectionSendTask::remove_sample(const DataSampleElement* element) { DBG_ENTRY("ThreadPerConnectionSendTask", "remove_sample"); GuardType guard(this->lock_); ACE_Message_Block* payload = element->get_sample()->cont(); ThreadPerConRemoveVisitor visitor(payload); this->queue_.accept_visitor(visitor); return visitor.status(); }
void SimpleDataWriter::init(const OpenDDS::DCPS::AssociationData& subscription) { DBG_ENTRY("SimpleDataWriter","init"); // Add the association between the local sub_id and the remote pub_id // to the transport via the TransportInterface. bool result = this->associate(subscription, true /* active */); if (!result) { ACE_ERROR((LM_ERROR, "(%P|%t) SimpleDataWriter::init() Failed to associate.\n")); throw TestException(); } }
int OpenDDS::DCPS::ThreadPerConnectionSendTask::remove_sample ( const DataSampleListElement* sample ) { DBG_ENTRY("ThreadPerConnectionSendTask","remove_sample"); GuardType guard(this->lock_); // Construct a PacketRemoveVisitor object. ThreadPerConRemoveVisitor vistor(sample->sample_); // Let it visit our elems_ collection as a "replace" visitor. this->queue_.accept_visitor(vistor); return vistor.status(); }
int SubDriver::parse_sub_arg(const ACE_TString& arg) { DBG_ENTRY("SubDriver","parse_sub_arg"); size_t pos; // Find the first ':' character, and make sure it is in a legal spot. if ((pos = std::find(arg.c_str(), arg.c_str() + arg.length(), ACE_TEXT(':')) - arg.c_str()) == arg.length()) { ACE_ERROR((LM_ERROR, "(%P|%t) Bad -p command-line value (%s). Missing ':' char.\n", arg.c_str())); return -1; } if (pos == 0) { ACE_ERROR((LM_ERROR, "(%P|%t) Bad -p command-line value (%s). " "':' char cannot be first char.\n", arg.c_str())); return -1; } if (pos == (arg.length() - 1)) { ACE_ERROR((LM_ERROR, "(%P|%t) Bad -p command-line value (%s) - " "':' char cannot be last char.\n", arg.c_str())); return -1; } // Parse the sub_id from left of ':' char, and remainder to right of ':'. ACE_TString sub_id_str(arg.c_str(), pos); this->sub_addr_str_ = arg.c_str() + pos + 1; // RepoIds are conventionally created and managed by the DCPSInfoRepo. Those // generated here are for the sole purpose of verifying internal behavior. OpenDDS::DCPS::RepoIdBuilder builder(sub_id_); builder.participantId(1); builder.entityKey(ACE_OS::atoi(sub_id_str.c_str())); builder.entityKind(OpenDDS::DCPS::ENTITYKIND_USER_WRITER_WITH_KEY); // Use the remainder as the "stringified" ACE_INET_Addr. this->sub_addr_ = ACE_INET_Addr(this->sub_addr_str_.c_str()); return 0; }
void SimpleDataWriter::data_delivered(const OpenDDS::DCPS::DataSampleElement* sample) { DBG_ENTRY("SimpleDataWriter","data_delivered"); ACE_UNUSED_ARG(sample); ACE_DEBUG((LM_DEBUG, "(%P|%t) The transport has confirmed that a sample has " "been delivered.\n")); //TBD: Cannot delete the sample here because this sample will be // used by the TransportInterface::send to look for the next // send sample. // Just leak here or put into a list for deletion later. // Delete the element //delete sample; ++this->num_messages_delivered_; }
void SimpleDataWriter::data_dropped(TAO::DCPS::DataSampleListElement* sample, bool dropped_by_transport) { DBG_ENTRY("SimpleDataWriter","data_dropped"); ACE_UNUSED_ARG(sample); ACE_UNUSED_ARG(dropped_by_transport); ACE_DEBUG((LM_DEBUG, "(%P|%t) The transport has confirmed that a sample has " "been dropped.\n")); //TBD: Cannot delete the sample here because this sample will be // used by the TransportInterface::send to look for the next // send sample. // Just leak here or put into a list for deletion later. // Delete the element //delete sample; this->delivered_test_message_ = 1; }
int OpenDDS::DCPS::ThreadPerConRemoveVisitor::visit_element_remove(SendRequest* element, int& remove) { DBG_ENTRY("ThreadPerConRemoveVisitor","visit_element_remove"); if ((this->sample_ != 0) && (element->op_ == SEND) && (*(element->element_) == this->sample_)) { // We are visiting the element that we want to remove, since the // element "matches" our sample_. // In order to have the BasicQueue<T> remove the element that we // are currently visiting, set the remove flag to true (1). The // BasicQueue<T> will perform the actual removal once we return // from this method. remove = 1; // Inform the element that we've made a decision - and it is // data_dropped() element->element_->data_dropped(); // Adjust our status_ to indicate that we actually found (and removed) // the sample. this->status_ = 1; if (this->sample_ != 0) { // Stop visitation since we've handled the element that matched // our sample_. return 0; } // When this->sample_ == 0, we visit every element. } // Continue visitation. return 1; }
int OpenDDS::DCPS::ThreadPerConnectionSendTask::close(u_long flag) { DBG_ENTRY("ThreadPerConnectionSendTask","close"); if (flag == 0) return 0; { GuardType guard(this->lock_); if (this->shutdown_initiated_) return 0; // Set the shutdown flag to true. this->shutdown_initiated_ = true; this->work_available_.signal(); } if (this->opened_ && this->thr_id_ != ACE_OS::thr_self()) this->wait(); return 0; }
SimpleDataWriter::SimpleDataWriter() : delivered_test_message_(0) { DBG_ENTRY("SimpleDataWriter","SimpleDataWriter"); }
SimpleDataWriter::~SimpleDataWriter() { DBG_ENTRY("SimpleDataWriter","~SimpleDataWriter"); }
int SimpleDataWriter::run(SimplePublisher* publisher) { DBG_ENTRY("SimpleDataWriter","run"); VDBG((LM_DEBUG, "(%P|%t) DBG: " "Build the DataSampleElementList to contain one element - " "our 'Hello World' string.\n")); // We just send one message. // This is what goes in the "Data Block". ACE_TString data = "Hello World!"; // Now we can create the DataSampleHeader struct and set its fields. TAO::DCPS::DataSampleHeader header; // The +1 makes the null terminator ('/0') get placed into the block. header.message_length_ = data.length() + 1; header.message_id_ = 1; header.sequence_ = 0; // TMB - Compiler no longer likes the next line... source_timestamp_ is gone. //header.source_timestamp_ = ACE_OS::gettimeofday().msec(); header.publication_id_ = this->pub_id_; // The DataSampleHeader is what goes in the "Header Block". ACE_Message_Block* header_block = new ACE_Message_Block (header.max_marshaled_size()); header_block << header; // The +1 makes the null terminator ('/0') get placed into the block. ACE_Message_Block* data_block = new ACE_Message_Block(data.length() + 1); data_block->copy(data.c_str()); // Chain the "Data Block" to the "Header Block" header_block->cont(data_block); // Create the DataSampleListElement now. TAO::DCPS::DataSampleListElementAllocator allocator(3); TAO::DCPS::TransportSendElementAllocator trans_allocator(3, sizeof (TAO::DCPS::TransportSendElement)); TAO::DCPS::DataSampleListElement* element; ACE_NEW_MALLOC_RETURN(element, static_cast<TAO::DCPS::DataSampleListElement*> (allocator.malloc(sizeof (TAO::DCPS::DataSampleListElement))), TAO::DCPS::DataSampleListElement(this->pub_id_, this, 0, &trans_allocator), 1); // The Sample Element will hold on to the chain of blocks (header + data). element->sample_ = header_block; // Set up the DataSampleList TAO::DCPS::DataSampleList samples; samples.head_ = element; samples.tail_ = element; samples.size_ = 1; VDBG((LM_DEBUG, "(%P|%t) DBG: " "Ask the publisher to send the DataSampleList (samples).\n")); publisher->send_samples(samples); VDBG((LM_DEBUG, "(%P|%t) DBG: " "The Publisher has finished sending the samples.\n")); return 0; }
PubDriver::~PubDriver() { DBG_ENTRY("PubDriver","~PubDriver"); }
SubDriver::~SubDriver() { DBG_ENTRY("SubDriver","~SubDriver"); }
OpenDDS::DCPS::ThreadPerConRemoveVisitor::~ThreadPerConRemoveVisitor() { DBG_ENTRY("ThreadPerConRemoveVisitor","~ThreadPerConRemoveVisitor"); }
void SimpleSubscriber::init(TAO::DCPS::TransportIdType transport_id, TAO::DCPS::RepoId sub_id, ssize_t num_publications, const TAO::DCPS::AssociationData* publications) { DBG_ENTRY("SimpleSubscriber","init"); VDBG((LM_DEBUG, "(%P|%t) DBG: " "Use TheTransportFactory to obtain() the TransportImpl object " "that it knows as transport_id (%d).\n", transport_id)); // Obtain the transport. TAO::DCPS::TransportImpl_rch transport = TheTransportFactory->obtain(transport_id); if (transport.is_nil()) { // Failed to obtain the transport. ACE_ERROR((LM_ERROR, "(%P|%t) Failed to obtain TransportImpl (id %d) from " "TheTransportFactory.\n", transport_id)); throw TestException(); } VDBG((LM_DEBUG, "(%P|%t) DBG: " "Attach ourselves (SimpleSubscriber) to the TransportImpl.\n")); // Attempt to attach the transport to ourselves. TAO::DCPS::AttachStatus status = this->attach_transport(transport.in()); if (status != TAO::DCPS::ATTACH_OK) { // We failed to attach to the transport for some reason. ACE_TString status_str; switch (status) { case TAO::DCPS::ATTACH_BAD_TRANSPORT: status_str = "ATTACH_BAD_TRANSPORT"; break; case TAO::DCPS::ATTACH_ERROR: status_str = "ATTACH_ERROR"; break; case TAO::DCPS::ATTACH_INCOMPATIBLE_QOS: status_str = "ATTACH_INCOMPATIBLE_QOS"; break; default: status_str = "Unknown Status"; break; } ACE_ERROR((LM_ERROR, "(%P|%t) Failed to attach to the transport. " "AttachStatus == %s\n", status_str.c_str())); throw TestException(); } // Good! We are now attached to the transport. VDBG((LM_DEBUG, "(%P|%t) DBG: " "SimpleSubscriber is now attached to the TransportImpl.\n")); VDBG((LM_DEBUG, "(%P|%t) DBG: " "Initialize our SimpleDataReader object.\n")); // Initialize our DataReader. this->reader_.init(sub_id); VDBG((LM_DEBUG, "(%P|%t) DBG: " "Add the publications.\n")); // Add the association between the local sub_id and the remote pub_id // to the transport via the TransportInterface. int result = this->add_publications(sub_id, &this->reader_, 0, /* priority */ num_publications, publications); if (result != 0) { ACE_ERROR((LM_ERROR, "(%P|%t) Failed to add publications to the " "TransportInterface.\n")); throw TestException(); } VDBG((LM_DEBUG, "(%P|%t) DBG: " "The publications have been added successfully.\n")); }
SimpleSubscriber::~SimpleSubscriber() { DBG_ENTRY("SimpleSubscriber","~SimpleSubscriber"); }
void SubDriver::parse_args(int& argc, ACE_TCHAR* argv[]) { DBG_ENTRY("SubDriver","parse_args"); // Command-line arguments: // // -p <pub_id:pub_host:pub_port> // -s <sub_id:sub_port> // -n <num_messages> // -m use shared memory // ACE_Arg_Shifter arg_shifter(argc, argv); bool got_n = false; bool got_p = false; bool got_s = false; const ACE_TCHAR* current_arg = 0; while (arg_shifter.is_anything_left()) { // The '-p' option if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-p")))) { if (got_p) { ACE_ERROR((LM_ERROR, "(%P|%t) Only one -p allowed on command-line.\n")); throw TestException(); } int result = parse_pub_arg(current_arg); arg_shifter.consume_arg(); if (result != 0) { ACE_ERROR((LM_ERROR, "(%P|%t) Failed to parse -p command-line arg.\n")); throw TestException(); } got_p = true; } // A '-s' option else if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-s")))) { if (got_s) { ACE_ERROR((LM_ERROR, "(%P|%t) Only one -s allowed on command-line.\n")); throw TestException(); } int result = parse_sub_arg(current_arg); arg_shifter.consume_arg(); if (result != 0) { ACE_ERROR((LM_ERROR, "(%P|%t) Failed to parse -s command-line arg.\n")); throw TestException(); } got_s = true; } // The '-n' option else if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-n")))) { if (got_n) { ACE_ERROR((LM_ERROR, "(%P|%t) Only one -n allowed on command-line.\n")); throw TestException(); } int value = ACE_OS::atoi(current_arg); arg_shifter.consume_arg(); if (value <= 0) { ACE_ERROR((LM_ERROR, "(%P|%t) Value following -n option must be > 0.\n")); throw TestException(); } this->num_msgs_ = value; got_n = true; } else if (arg_shifter.cur_arg_strncasecmp(ACE_TEXT("-m")) == 0) { this->shmem_ = true; arg_shifter.consume_arg(); } // The '-?' option else if (arg_shifter.cur_arg_strncasecmp(ACE_TEXT("-?")) == 0) { ACE_DEBUG((LM_DEBUG, "usage: %s " "-p pub_id:pub_host:pub_port -s sub_id:sub_host:sub_port\n", argv[0])); arg_shifter.consume_arg(); throw TestException(); } // Anything else we just skip else { arg_shifter.ignore_arg(); } } // Make sure we got the required arguments: if (!got_p) { ACE_ERROR((LM_ERROR, "(%P|%t) -p command-line option not specified (required).\n")); throw TestException(); } if (!got_s) { ACE_ERROR((LM_ERROR, "(%P|%t) -s command-line option not specified (required).\n")); throw TestException(); } }