// // handle_input // int CUTS_TCPIP_Event_Handler::handle_input (ACE_HANDLE fd) { // Set the ACE_HANDLE as a socket stream. ACE_SOCK_Stream stream (fd); // @todo Since the header size is constant, we can create free list // of the message blocks that are used to read the header from // the stream. // Read the event from the stream. The first chunk of the event // is be the header information, which is of constrant size. static const ssize_t header_size = 4 + // magic 4 + // byte order 2 + // version (x.x) 2 + // padding 16 + // UUID 4 + // event id 4; // payload size ACE_Message_Block header (header_size); ssize_t retcode = stream.recv_n (header.wr_ptr (), header_size); if (retcode != header_size) ACE_ERROR_RETURN ((LM_ERROR, "%T (%t) - %M - invalid TCP/IP header\n"), -1); // Reflect the number of bytes read from the stream. header.wr_ptr (header_size); // Extract the header from the message block. CUTS_TCPIP_SPEC spec; ACE_CDR::ULong datasize; ACE_InputCDR input (header.rd_ptr (), header_size); // Read the SPEC and the datasize from the packet. input >> spec; input >> datasize; if (!input.good_bit ()) ACE_ERROR_RETURN ((LM_ERROR, "%T (%t) - %M - failed to read TCP/IP header\n"), -1); // Construct a chain of message blocks to read the payload associated // with the received event. ACE_Message_Block * mb = 0; ACE_NEW_RETURN (mb, ACE_Message_Block (ACE_CDR::DEFAULT_BUFSIZE), -1); ssize_t read_count; ACE_Message_Block * head = mb; ACE_Auto_Ptr <ACE_Message_Block> auto_clean (head); for (size_t remaining = datasize; 0 != remaining; ) { // Determine how much should be read in this attempt. read_count = ACE_CDR::DEFAULT_BUFSIZE < remaining ? ACE_CDR::DEFAULT_BUFSIZE : remaining; // Read the data from the stream. retcode = stream.recv_n (mb->wr_ptr (), read_count); if (retcode != read_count) ACE_ERROR_RETURN ((LM_ERROR, "%T - %M - %m\n"), -1); // Substract the amount from the remaining count. mb->wr_ptr (read_count); remaining -= read_count; if (0 != remaining) { // Allocate a new block for the chain. ACE_Message_Block * temp = 0; ACE_NEW_RETURN (temp, ACE_Message_Block (ACE_CDR::DEFAULT_BUFSIZE), -1); // Insert new block in the chain and move forward. mb->cont (temp); mb = temp; } } // Since we have made it this far, we have successfully read the // event and its payload from the socket. Now, pass the message // the object manger, so it can dispatch it accordingly. if (this->obj_mgr_ != 0) { iCCM::TCPIP_Servant * svnt = 0; int retval = this->obj_mgr_->find_object (spec.uuid_, svnt); if (0 == retval) { // Signal the object to handle the event. ACE_InputCDR ev (head, input.byte_order ()); retval = svnt->handle_event (spec.event_id_, ev); if (-1 == retval) ACE_ERROR ((LM_ERROR, "%T (%t) - %M - failed to handle event [%s]\n", spec.uuid_.to_string ()->c_str ())); } else ACE_ERROR ((LM_ERROR, "%T (%t) - %M - failed to locate object with id [%s]\n", spec.uuid_.to_string ()->c_str ())); } // Release the message block. // head->release (); return 0; }
int Receiver::handle_input (ACE_HANDLE h) { ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, locker, this->mutex_, -1); ACE_Message_Block *mb = 0; ACE_NEW_RETURN (mb, ACE_Message_Block (BUFSIZ), -1); int err = 0; ssize_t res = this->peer ().recv (mb->rd_ptr (), BUFSIZ-1); this->total_r_++; if (res >= 0) { mb->wr_ptr (res); this->total_rcv_ += res; } else err = errno ; mb->wr_ptr ()[0] = '\0'; if (loglevel == 0 || res <= 0 || err!= 0) { LogLocker log_lock; ACE_DEBUG ((LM_DEBUG, "**** Receiver::handle_input () SessionId=%d****\n", index_)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "bytes_to_read", BUFSIZ)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "handle", h)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "bytes_transferred", res)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "error", err)); ACE_DEBUG ((LM_DEBUG, "%C = %s\n", "message_block", mb->rd_ptr ())); ACE_DEBUG ((LM_DEBUG, "**** end of message ****************\n")); } if (err == EWOULDBLOCK) { err=0; res=0; return check_destroy (); } if (err !=0 || res <= 0) { ACE_Message_Block::release (mb); return -1; } ACE_Time_Value tv = ACE_Time_Value::zero; int qcount = this->putq (mb, & tv); if (qcount <= 0) // failed to putq { ACE_Message_Block::release (mb); return -1 ; } int rc = 0; if (duplex == 0) // half-duplex , stop read rc = this->terminate_io (ACE_Event_Handler::READ_MASK); else // full duplex { if (qcount >= 20 ) // flow control, stop read rc = this->terminate_io (ACE_Event_Handler::READ_MASK); else rc = this->initiate_io (ACE_Event_Handler::READ_MASK); } if (rc == -1) return -1; //initiate write if (this->initiate_io (ACE_Event_Handler::WRITE_MASK) != 0) return -1; return check_destroy (); }
void JAWS_Config_File_Impl::parse_file (void) { ACE_FILE_Connector fconnector; ACE_FILE_IO fio; if (fconnector.connect ( fio , this->faddr_ , 0 , ACE_Addr::sap_any , 0 , O_RDONLY ) == -1) return; ACE_Message_Block buffer (8192); ACE_Message_Block line (4096); ssize_t count = 0; const ACE_TCHAR *sym_name; const ACE_TCHAR *sym_value; int last_line_was_read = 0; ACE_TCHAR *end_of_current_line = 0; ACE_TCHAR *p = 0; while (last_line_was_read || (count = fio.recv (buffer.wr_ptr (), buffer.space () - 2)) >= 0) { end_of_current_line = 0; // Make sure input is newline terminated if it is the last line, // and always null terminated. if (! last_line_was_read) { if (count > 0) { buffer.wr_ptr (count); // Scan forward for at least one newline character p = buffer.rd_ptr (); while (p != buffer.wr_ptr ()) { if (*p == '\n') break; p++; } if (p == buffer.wr_ptr ()) continue; end_of_current_line = p; } else { if (buffer.wr_ptr ()[-1] != '\n') { buffer.wr_ptr ()[0] = '\n'; buffer.wr_ptr (1); } last_line_was_read = 1; } buffer.wr_ptr ()[0] = '\0'; } if (end_of_current_line == 0) { end_of_current_line = buffer.rd_ptr (); while (*end_of_current_line != '\n') end_of_current_line++; } // If buffer is not pointing to a continuation line, or there is // no more input, then can commit the scanned configuration // line. if (line.length () != 0 && ((last_line_was_read && buffer.length () == 0) || (buffer.rd_ptr ()[0] != ' ' && buffer.rd_ptr ()[0] != '\t'))) { ACE_TCHAR *name = 0; ACE_TCHAR *value = 0; name = line.rd_ptr (); for (p = name; *p != '\0'; p++) { if (*p == '=') { line.rd_ptr (p+1); while (p != name && (p[-1] == ' ' || p[-1] == '\t')) p--; *p = '\0'; } } if (*name) { value = line.rd_ptr (); while (*value == ' ' || *value == '\t') value++; p = line.wr_ptr (); while (p != value && (p[-1] == ' ' || p[-1] == '\t')) p--; *p = '\0'; sym_name = this->strings_->duplicate (name); sym_value = this->strings_->duplicate (value); this->symbols_->rebind (sym_name, sym_value); } line.reset (); } // If we are done, we are done! if (last_line_was_read && buffer.length () == 0) break; // If the buffer is pointing at a comment line, ignore it. if (buffer.rd_ptr ()[0] == '#' || buffer.rd_ptr ()[0] == '\n' || (buffer.rd_ptr ()[0] == '\r' && buffer.rd_ptr ()[1] == '\n')) { buffer.rd_ptr (end_of_current_line + 1); buffer.crunch (); continue; } // Whatever is left is either the start of a name-value-pair or a // continuation of one. line.copy (buffer.rd_ptr (), end_of_current_line - buffer.rd_ptr ()); p = line.wr_ptr (); while (p != line.rd_ptr () && (p[-1] == ' ' || p[-1] == '\t')) p--; line.wr_ptr (p); line.wr_ptr ()[0] = '\0'; buffer.rd_ptr (end_of_current_line + 1); buffer.crunch (); } fio.close (); }
int DC_Service_Request::do_request(KSG_WORK_SVR_HANDLER *handle) { ACE_Message_Block *mblk = handle->mblk_; ACE_SOCK_Stream peer; ACE_Message_Block *resp_buf; unsigned char *msg_begin = (unsigned char*)mblk->rd_ptr(); unsigned char *out_buf; unsigned char crc_code[4]; int data_len = mblk->length(); short pack_len; int len; int ret; peer.set_handle(handle->handle_); ACE_HEX_DUMP((LM_DEBUG,mblk->rd_ptr(),mblk->length())); if(msg_begin[0]!=0xC0 && msg_begin[data_len]!=0xC1) { ACE_DEBUG((LM_ERROR,"收到数据包起始符错误...")); return -1; } BUF_2_SHORT_BE(pack_len,(msg_begin+1)); if(data_len - 3 < pack_len ) { ACE_DEBUG((LM_ERROR,"收到错误数据包长度错误...")); return -1; } // check crc /* pack_len = GenerateCRC16(msg_begin+3,data_len-3-3); SHORT_2_BUF_BE(pack_len,crc_code); if(memcmp(crc_code,msg_begin+data_len-3,2)!=0) { ACE_DEBUG((LM_ERROR,"收到数据包CRC校验错误...")); return 0; } */ if(calc_sum(msg_begin+3,data_len-3-2)!=msg_begin[data_len-2]) { ACE_DEBUG((LM_ERROR,"收到数据包CRC校验错误...")); return 0; } ACE_NEW_RETURN(resp_buf,ACE_Message_Block(128),-1); len = 0; out_buf = (unsigned char*)resp_buf->wr_ptr(); out_buf[0]=0xC2; out_buf[3]=msg_begin[3]; switch(msg_begin[3]) { case 0x70: ret = do_upload_serial(msg_begin,data_len,out_buf+4,len); break; case 0x71: ret = do_download_blkcard(msg_begin,data_len,out_buf+4,len); break; default: ret = -1; break; } if(ret == 1) { if(len > 0) { // 计算CRC out_buf[4+len]=calc_sum(out_buf+3,len+1); len+=5; out_buf[len++] = 0xC3; pack_len = len - 3; SHORT_2_BUF_BE(pack_len,(out_buf+1)); resp_buf->wr_ptr(len); ACE_HEX_DUMP((LM_DEBUG,resp_buf->rd_ptr(),resp_buf->length())); ACE_Time_Value tv(0); if(peer.send_n(resp_buf,&tv) <=0 ) { ACE_DEBUG((LM_ERROR,"发送应答包失败")); ret = -1; } else { ret = 1; } } else ret = 0; } resp_buf->release(); return ret; }
static void * peer1 (void *) { ACE_UPIPE_Stream c_stream; ACE_DEBUG ((LM_DEBUG, "(%t) peer1 starting connect\n")); ACE_UPIPE_Connector con; if (con.connect (c_stream, addr) == -1) ACE_ERROR ((LM_ERROR, "(%t) peer1 ACE_UPIPE_Connector failed\n")); ACE_Message_Block *mb; ACE_NEW_RETURN (mb, ACE_Message_Block (20), 0); mb->copy ("hello", 6); if (c_stream.send (mb) == -1) ACE_ERROR ((LM_ERROR, "(%t) error peer1 send\n")); if (c_stream.recv (mb) == -1) ACE_ERROR ((LM_ERROR, "(%t) error peer1 recv\n")); ACE_ERROR ((LM_ERROR, "(%t) peer1 ack is \"%s\"\n", mb->rd_ptr ())); // Free up the memory block. mb->release (); // Now try the send()/recv() interface. char mytext[] = "This string is sent by peer1 as buffer"; ACE_ERROR ((LM_ERROR, "(%t) peer1 sending text\n")); if (c_stream.send (mytext, sizeof mytext) == -1) ACE_ERROR ((LM_ERROR, "(%t) buffer send from peer1 failed\n")); char conbuf[30]; // Buffer to receive response. int i = 0; for (char c = ' '; c != '!'; i++) { if (c_stream.recv (&c, 1) == -1) ACE_ERROR ((LM_ERROR, "(%t) buffer recv from peer1 failed\n")); else conbuf[i] = c; } conbuf[i] = '\0'; ACE_DEBUG ((LM_DEBUG, "(%t) peer1 received buffer with \"%s\"\n", conbuf)); c_stream.close (); return 0; }
static int query_aio_completions (void) { for (size_t number_of_compleions = 0; number_of_compleions < 3; number_of_compleions ++) { // Wait for <milli_seconds> amount of time. @@ Assigning // <milli_seconds> to tv_sec. timespec timeout; timeout.tv_sec = ACE_INFINITE; timeout.tv_nsec = 0; // To get back the signal info. siginfo_t sig_info; // Await the RT completion signal. int sig_return = ACE_OS::sigtimedwait (&completion_signal, &sig_info, &timeout); // Error case. // If failure is coz of timeout, then return *0* but set // errno appropriately. This is what the WinNT proactor // does. if (sig_return == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error: %p\n", "Error waiting for RT completion signals"), -1); //FUZZ: disable check_for_lack_ACE_OS // RT completion signals returned. if (sig_return != SIGRTMIN) ACE_ERROR_RETURN ((LM_ERROR, "Unexpected signal (%d) has been received while waiting for RT Completion Signals\n", sig_return), -1); //FUZZ: enble check_for_lack_ACE_OS // @@ Debugging. ACE_DEBUG ((LM_DEBUG, "Sig number found in the sig_info block : %d\n", sig_info.si_signo)); // Is the signo returned consistent? if (sig_info.si_signo != sig_return) ACE_ERROR_RETURN ((LM_ERROR, "Inconsistent signal number (%d) in the signal info block\n", sig_info.si_signo), -1); // @@ Debugging. ACE_DEBUG ((LM_DEBUG, "Signal code for this signal delivery : %d\n", sig_info.si_code)); // Is the signal code an aio completion one? if ((sig_info.si_code != SI_ASYNCIO) && (sig_info.si_code != SI_QUEUE)) ACE_ERROR_RETURN ((LM_DEBUG, "Unexpected signal code (%d) returned on completion querying\n", sig_info.si_code), -1); // Retrive the aiocb. aiocb* aiocb_ptr = (aiocb *) sig_info.si_value.sival_ptr; if (aiocb_ptr == &aiocb3) { ACE_ASSERT (sig_info.si_code == SI_QUEUE); ACE_DEBUG ((LM_DEBUG, "sigqueue caught... good\n")); } else { // Analyze error and return values. Return values are // actually <errno>'s associated with the <aio_> call // corresponding to aiocb_ptr. int error_code = aio_error (aiocb_ptr); if (error_code == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Invalid control block was sent to <aio_error> for completion querying"), -1); if (error_code != 0) // Error occurred in the <aio_>call. Return the errno // corresponding to that <aio_> call. ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "An AIO call has failed"), error_code); // No error occurred in the AIO operation. int nbytes = aio_return (aiocb_ptr); if (nbytes == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Invalid control block was send to <aio_return>"), -1); if (number_of_compleions == 0) { // Print the buffer. ACE_DEBUG ((LM_DEBUG, "\n Number of bytes transferred : %d\n", nbytes)); // Note... the dumps of the buffers are disabled because they // may easily overrun the ACE_Log_Msg output buffer. If you need // to turn the on for some reason, be careful of this. #if 0 ACE_DEBUG ((LM_DEBUG, "The buffer : %s\n", mb1.rd_ptr ())); #endif /* 0 */ } else { // Print the buffer. ACE_DEBUG ((LM_DEBUG, "\n Number of bytes transferred : %d\n", nbytes)); #if 0 ACE_DEBUG ((LM_DEBUG, "The buffer : %s\n", mb2.rd_ptr ())); #endif /* 0 */ } } } return 0; }
ACE_Message_Block * ACE_Message_Block::duplicate (void) const { ACE_TRACE ("ACE_Message_Block::duplicate"); ACE_Message_Block *nb = 0; // Create a new <ACE_Message_Block> that contains unique copies of // the message block fields, but a reference counted duplicate of // the <ACE_Data_Block>. // If there is no allocator, use the standard new and delete calls. if (this->message_block_allocator_ == 0) ACE_NEW_RETURN (nb, ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, ACE_DEADLINE_TIME, // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). this->data_block ()->duplicate (), this->data_block ()->data_block_allocator (), this->message_block_allocator_), 0); else // Otherwise, use the message_block_allocator passed in. ACE_NEW_MALLOC_RETURN (nb, static_cast<ACE_Message_Block*> ( message_block_allocator_->malloc (sizeof (ACE_Message_Block))), ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, ACE_DEADLINE_TIME, // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). this->data_block ()->duplicate (), this->data_block ()->data_block_allocator (), this->message_block_allocator_), 0); // Set the read and write pointers in the new <Message_Block> to the // same relative offset as in the existing <Message_Block>. Note // that we are assuming that the data_block()->base() pointer // doesn't change when it's duplicated. nb->rd_ptr (this->rd_ptr_); nb->wr_ptr (this->wr_ptr_); // Increment the reference counts of all the continuation messages. if (this->cont_) { nb->cont_ = this->cont_->duplicate (); // If things go wrong, release all of our resources and return // 0. if (nb->cont_ == 0) { nb->release (); nb = 0; } } return nb; }
int Task::svc (void) { // This is the function that our service threads run once they are spawned. ACE_DEBUG ((LM_DEBUG, " (%P|%t) %s Task::svc () -- once per servicing thread\n", d_nameOfTask)); // First, we wait until all of our peer service threads have arrived // at this point also. d_barrier.wait (); ACE_Message_Block *messageBlock; while (1) { // And now we loop almost infinitely. // getq () will block until a Message_Block is available to be read, // or an error occurs. if ( this->getq (messageBlock, 0) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc () getq"), -1); } if (messageBlock->msg_type () == ACE_Message_Block::MB_HANGUP) { // If the Message_Block is of type MB_HANGUP, then we're being asked // to shut down nicely. ACE_DEBUG ((LM_DEBUG, " (%P|%t) %s Task::svc () -- HANGUP block received\n", d_nameOfTask)); // So, we duplicate the Block, and put it back into the Message_Queue, // in case there are some more peer service threads still running. if (this->putq (messageBlock->duplicate ()) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc () putq"), -1); } // We release our copy of the Block. messageBlock->release (); // And we break out of the nearly infinitely loop, and // head towards close () ourselves. break; } // If we're here, then we've received a Message_Block that was // not informing us to quit, so we're assuming it's a valid // meaningful Block. ACE_DEBUG ((LM_DEBUG, " (%P|%t) %s Task::svc () -- Normal block received\n", d_nameOfTask)); // We grab the read-pointer from the Block, and display it through a DEBUG statement. ACE_DEBUG ((LM_DEBUG, " (%P|%t) %s Task::svc () -- %s\n", d_nameOfTask, messageBlock->rd_ptr () )); // We pretend that this takes to time to process the Block. // If you're on a fast machine, you might have to raise this // value to actually witness different threads handling // blocks for each Task. ACE_OS::sleep (ACE_Time_Value (0, 250)); // Since we're part of a Stream, we duplicate the Block, and // send it on to the next Task. if (put_next (messageBlock->duplicate ()) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc () put_next"), -1); } // And then we release our copy of it. messageBlock->release (); } return 0; }
int GadgetStreamController::svc(void) { while (true) { GadgetMessageIdentifier id; ssize_t recv_cnt = 0; if ((recv_cnt = peer().recv_n (&id, sizeof(GadgetMessageIdentifier))) <= 0) { GERROR("GadgetStreamController, unable to read message identifier\n"); return -1; } if (id.id == GADGET_MESSAGE_CLOSE) { stream_.close(1); //Shutdown gadgets and wait for them GDEBUG("Stream closed\n"); GDEBUG("Closing writer task\n"); this->writer_task_.close(1); GDEBUG("Writer task closed\n"); continue; } GadgetMessageReader* r = readers_.find(id.id); if (!r) { GERROR("Unrecognized Message ID received: %d\n", id.id); return GADGET_FAIL; } ACE_Message_Block* mb = r->read(&peer()); if (!mb) { GERROR("GadgetMessageReader returned null pointer\n"); return GADGET_FAIL; } //We need to handle some special cases to make sure that we can get a stream set up. if (id.id == GADGET_MESSAGE_CONFIG_FILE) { GadgetContainerMessage<GadgetMessageConfigurationFile>* cfgm = AsContainerMessage<GadgetMessageConfigurationFile>(mb); if (!cfgm) { GERROR("Failed to cast message block to configuration file\n"); mb->release(); return GADGET_FAIL; } else { if (this->configure_from_file(std::string(cfgm->getObjectPtr()->configuration_file)) != GADGET_OK) { GERROR("GadgetStream configuration failed\n"); mb->release(); return GADGET_FAIL; } else { mb->release(); continue; } } } else if (id.id == GADGET_MESSAGE_CONFIG_SCRIPT) { std::string xml_config(mb->rd_ptr(), mb->length()); if (this->configure(xml_config) != GADGET_OK) { GERROR("GadgetStream configuration failed\n"); mb->release(); return GADGET_FAIL; } else { mb->release(); continue; } } ACE_Time_Value wait = ACE_OS::gettimeofday() + ACE_Time_Value(0,10000); //10ms from now if (stream_.put(mb) == -1) { GERROR("Failed to put stuff on stream, too long wait, %d\n", ACE_OS::last_error () == EWOULDBLOCK); mb->release(); return GADGET_FAIL; } } return GADGET_OK; }
void DSession::handle_write_dgram(const TRB_Asynch_Write_Dgram::Result &result) { { ACE_GUARD (ACE_SYNCH_MUTEX, monitor, this->lock_); this->io_count_w_--; int loglevel = cfg.loglevel(); ACE_Message_Block *mb = result.message_block (); size_t xfer_bytes = result.bytes_transferred(); char * last = mb->rd_ptr(); char * first = last - xfer_bytes; u_long error = result.error (); const ACE_Addr & addr = result.remote_address (); ACE_INET_Addr peerAddr ((u_short)0); if (addr.get_type () == peerAddr.get_type ()) { // copy the remote_address_ into addr peerAddr.set_addr (addr.get_addr(), addr.get_size()); } if (cfg.loglevel () == 0) { LogLocker log_lock; //mb.rd_ptr () [0] = '\0'; mb->rd_ptr (mb->rd_ptr () - result.bytes_transferred ()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) **** %s=%d handle_write_dgram() ****\n"), this->get_name(), this->index())); this->print_address (result.remote_address()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("bytes_to_write"), result.bytes_to_write ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("handle"), result.handle ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("bytes_transfered"), result.bytes_transferred ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("error"), error)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("message_block:\n"))); ACE_HEX_DUMP ((LM_DEBUG, first, xfer_bytes)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("**** end of message ****************\n"))); } else if (error != 0) { LogLocker log_lock; this->print_address (result.remote_address()); ACE_OS::last_error (error); ACE_Log_Msg::instance ()->errnum (error); ACE_Log_Msg::instance ()->log (LM_ERROR, ACE_TEXT ("(%t) %s=%d WRITE ERROR=%d %p\n"), this->get_name (), this->index (), error, ACE_TEXT (":")); } else if (loglevel == 1) { LogLocker log_lock; this->print_address (result.remote_address()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) %s=%d WRITE=%d bytes ok\n"), this->get_name (), this->index (), result.bytes_transferred ())); } if (error == 0 && result.bytes_transferred () > 0) { this->total_snd_ += result.bytes_transferred (); } else { mb->msg_type (ACE_Message_Block::MB_ERROR); mb->wr_ptr (mb->rd_ptr()); } this->on_data_sent (*mb, peerAddr); if (this->io_count_r_ != 0 || this->io_count_w_ != 0 || this->post_count_ != 0 ) return; } delete this; }
int Worker_Task::svc (void) { // The <ACE_Task::svc_run()> method automatically adds us to the // process-wide <ACE_Thread_Manager> when the thread begins. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) starting svc() method\n"))); // Keep looping, reading a message out of the queue, until we get a // message with a length == 0, which signals us to quit. for (int count = 0; ; count++) { ACE_Message_Block *mb = 0; if (-1 == this->msg_queue ()->dequeue_head (mb)) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("Worker_Task dequeue_head"))); size_t length = mb->length (); // If there's a next() Task then "logically" copy the message by // calling <duplicate> and send it on down the pipeline. Note // that this doesn't actually make a copy of the message // contents (i.e., the Data_Block portion), it just makes a copy // of the header and reference counts the data. if (this->next () != 0) { if (-1 == this->put_next (mb->duplicate ())) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("Worker_Task put_next"))); } // If there's no next() Task to send to, then we'll consume the // message here. else if (length > 0) { int current_count = ACE_OS::atoi ((ACE_TCHAR *)(mb->rd_ptr ())); int i; if (count != current_count) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) count from block should be %d ") ACE_TEXT ("but is %d\n"), count, current_count)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) enqueueing %d duplicates\n"), current_count)); ACE_Message_Block *dup; // Enqueue <current_count> duplicates with msg_priority == 1. for (i = current_count; i > 0; i--) { ACE_ALLOCATOR_RETURN (dup, mb->duplicate (), -1); // Set the priority to be greater than "normal" // messages. Therefore, all of these messages should go // to the "front" of the queue, i.e., ahead of all the // other messages that are being enqueued by other // threads. dup->msg_priority (ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY + 1); int enqueue_prio_result = this->msg_queue ()->enqueue_prio (dup, // Don't block indefinitely if we flow control... (ACE_Time_Value *) &ACE_Time_Value::zero); if (enqueue_prio_result == -1) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) Pass %d %p\n"), i, ACE_TEXT ("Worker_Task enqueue_prio"))); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) dequeueing %d duplicates\n"), current_count)); // Dequeue the same <current_count> duplicates. for (i = current_count; i > 0; i--) { if (-1 == this->msg_queue ()->dequeue_head (dup)) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) Dup %d, %p\n"), i, ACE_TEXT ("Worker_Task dequeue dups"))); if (count != ACE_OS::atoi ((ACE_TCHAR *)(dup->rd_ptr ()))) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) line %l, Dup %d, block's count ") ACE_TEXT ("is %d but should be %d\n"), i, ACE_OS::atoi ((ACE_TCHAR *)(dup->rd_ptr ())), count)); if (0 != ACE_OS::strcmp ((ACE_TCHAR *)mb->rd_ptr (), (ACE_TCHAR *)dup->rd_ptr ())) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) Dup %d text is %s; ") ACE_TEXT ("should be %s\n"), i, dup->rd_ptr (), mb->rd_ptr ())); if (dup->msg_priority () != ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY + 1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) Dup %d block priority is %u; ") ACE_TEXT ("should be %u\n"), i, (unsigned int)dup->msg_priority (), (unsigned int)(ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY + 1))); dup->release (); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) in iteration %d, length = %B, prio = %d, text = \"%*s\"\n"), count, length, mb->msg_priority (), (int)(length - 2), // remove the trailing "\n\0" mb->rd_ptr ())); } // We're responsible for deallocating this. mb->release (); if (length == 0) { //FUZZ: disable check_for_NULL ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) in iteration %d, queue len = %B, got NULL message, exiting\n"), count, this->msg_queue ()->message_count ())); //FUZZ: enable check_for_NULL break; } } // Note that the ACE_Task::svc_run () method automatically removes // us from the Thread_Manager when the thread exits. return 0; }
void DSession::handle_read_dgram (const TRB_Asynch_Read_Dgram::Result &result) { { ACE_GUARD (ACE_SYNCH_MUTEX, monitor, this->lock_ ); this->io_count_r_--; int loglevel = cfg.loglevel(); ACE_Message_Block *mb = result.message_block (); size_t xfer_bytes = result.bytes_transferred(); char * last = mb->wr_ptr(); char * first = last - xfer_bytes; u_long error = result.error (); if (loglevel == 0) { LogLocker log_lock; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) **** %s=%d handle_read_dgram() ****\n"), this->get_name(), this->index())); this->print_address (result.remote_address()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("bytes_to_read"), result.bytes_to_read ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("handle"), result.handle ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("bytes_transfered"), result.bytes_transferred ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s = %d\n"), ACE_TEXT ("error"), error)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("message_block:\n"))); ACE_HEX_DUMP ((LM_DEBUG, first, xfer_bytes)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("**** end of message ****************\n"))); } else if (error != 0) { LogLocker log_lock; this->print_address (result.remote_address()); ACE_OS::last_error (error); ACE_Log_Msg::instance ()->errnum (error); ACE_Log_Msg::instance ()->log (LM_ERROR, ACE_TEXT ("(%t) %s=%d READ ERROR=%d %p\n"), this->get_name (), this->index (), error, ACE_TEXT (":")); } else if (loglevel == 1) { LogLocker log_lock; this->print_address (result.remote_address()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) %s=%d READ=%d bytes ok\n"), this->get_name (), this->index (), result.bytes_transferred ())); } do_delay (cfg.delay()); // delay milliseconds if (error == 0 && result.bytes_transferred () > 0) { this->total_rcv_ += result.bytes_transferred (); } else { mb->msg_type (ACE_Message_Block::MB_HANGUP); mb->wr_ptr (mb->rd_ptr()); } this->on_data_received (*mb, static_cast<const ACE_INET_Addr&> (result.remote_address())); if (this->io_count_r_ != 0 || this->io_count_w_ != 0 || this->post_count_ != 0 ) return; } delete this; }
int Sender::handle_output (ACE_HANDLE h) { ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, locker, this->mutex_, -1); ACE_Time_Value tv = ACE_Time_Value::zero; ACE_Message_Block *mb = 0; int err=0; ssize_t res=0; size_t bytes=0; int qcount = this->getq (mb , & tv); if (mb != 0) // qcount >= 0 { bytes = mb->length (); res = this->peer ().send (mb->rd_ptr (), bytes); this->total_w_++; if (res < 0) err = errno ; else this->total_snd_ += res; if (loglevel == 0 || res <= 0 || err!= 0) { LogLocker log_lock; ACE_DEBUG ((LM_DEBUG, "**** Sender::handle_output () SessionId=%d****\n", index_)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "bytes_to_write", bytes)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "handle", h)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "bytes_transferred", res)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "error", err)); ACE_DEBUG ((LM_DEBUG, "%C = %s\n", "message_block", mb->rd_ptr ())); ACE_DEBUG ((LM_DEBUG, "**** end of message ****************\n")); } } ACE_Message_Block::release (mb); if (err != 0 || res < 0) return -1; int rc = 0; if (qcount <= 0) // no more message blocks in queue { if (duplex != 0 && // full duplex, continue write (this->total_snd_ - this->total_rcv_ ) < 1024*32 ) // flow control rc = initiate_write (); else rc = terminate_io (ACE_Event_Handler::WRITE_MASK); if (rc == -1) return -1; } rc = initiate_io (ACE_Event_Handler::READ_MASK); if (rc == -1) return -1; return check_destroy (); }
int Sender::handle_input (ACE_HANDLE h) { ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, locker, this->mutex_, -1); ACE_Message_Block *mb = 0; ACE_NEW_RETURN (mb, ACE_Message_Block (BUFSIZ), -1); int err = 0; ssize_t res = this->peer ().recv (mb->rd_ptr (), BUFSIZ-1); this->total_r_++; if (res >= 0) { mb->wr_ptr (res); this->total_rcv_ += res; } else err = errno ; mb->wr_ptr ()[0] = '\0'; if (loglevel == 0 || res <= 0 || err!= 0) { LogLocker log_lock; ACE_DEBUG ((LM_DEBUG, "**** Sender::handle_input () SessionId=%d****\n", index_)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "bytes_to_read", BUFSIZ)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "handle", h)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "bytes_transferred", res)); ACE_DEBUG ((LM_DEBUG, "%C = %d\n", "error", err)); ACE_DEBUG ((LM_DEBUG, "%C = %s\n", "message_block", mb->rd_ptr ())); ACE_DEBUG ((LM_DEBUG, "**** end of message ****************\n")); } ACE_Message_Block::release (mb); if (err == EWOULDBLOCK) { err=0; res=0; return check_destroy (); } if (err !=0 || res <= 0) return -1; int rc = 0; if (duplex != 0) // full duplex, continue read rc = initiate_io (ACE_Event_Handler::READ_MASK); else rc = terminate_io (ACE_Event_Handler::READ_MASK); if (rc != 0) return -1 ; rc = initiate_write (); if (rc != 0) return -1; return check_destroy (); }
int JAWS_Parse_Headers::parse_headers (JAWS_Header_Info *info, ACE_Message_Block &mb) { for (;;) { if (mb.rd_ptr () == mb.wr_ptr ()) break; char *p = mb.rd_ptr (); if (info->end_of_line () && (*p != ' ' && *p != '\t')) { int r = this->parse_header_name (info, mb); if (r == 1) return info->end_of_headers (); continue; } else { int r = this->parse_header_value (info, mb); if (r == 1) { if (info->end_of_headers ()) return 1; break; } continue; } } // If we arrive here, it means either there is nothing more to read, // or parse_header_value ran into difficulties (like maybe the // header value was too long). if (mb.rd_ptr () != mb.base ()) { mb.crunch (); return 0; } else if (mb.length () < mb.size ()) { return 0; } else if (mb.length () == mb.size ()) { // This is one of those cases that should rarely ever happen. // If we get here, the header type name is over 8K long. We // flag this as a bad thing. // In HTTP/1.1, I have to remember that a bad request means the // connection needs to be closed and the client has to // reinitiate the connection. info->status (JAWS_Header_Info::STATUS_CODE_TOO_LONG); return 1; } else if (mb.length () > mb.size ()) { ACE_DEBUG ((LM_DEBUG, "JAWS_Parse_Headers: buffer overrun!!\n")); info->status (JAWS_Header_Info::STATUS_CODE_TOO_LONG); return 1; } ACE_DEBUG ((LM_DEBUG, "JAWS_Parse_Headers -- shouldn't be here!\n")); return 1; }
int Request::appendBody(const char* buf, const size_t bufSize) { ACE_ASSERT(buf); ACE_ASSERT(bufSize > 0); // 아래를 안해 주면 대용량 처리할 때 문제가 된다. // bufSize 는 recv Buffer 사이즈로 4K 정도이다. // 메모리 할당/해제 회수를 줄일려면 아래를 실행 해 주어야 한다. if (pRawBody == NULL) { // 아래를 안해 주면 대용량 처리할 때 문제가 된다. // 메모리 할당/해제 회수를 줄일려면 아래를 실행 해 주어야 한다. size_t newSize = std::max(bufSize, contentLength); // chunk 인 경우 빨리 버퍼를 충분히 할당하기 위해. (2007.1.3) // 빈번한 버퍼 크기 확장을 막기 위해, 초기 최소 사이즈를 제한 newSize = std::max(newSize, (size_t)CHUNK_INIT_BUFFSIZE); pRawBody = pMBManager->alloc(newSize); if(pRawBody == NULL) { PAS_ERROR("Request::appendBody, AllocMessageBlock fail!!"); return -1; } } ACE_ASSERT(pRawBody != NULL); if(pRawBody->space() < bufSize) { // 기존 수신데이터 사이즈에 따른 셋팅 - 기존 사이즈의 배수로 증가. size_t newSize = std::max((pRawBody->size() + (bufSize * 2)), (pRawBody->size() * 2)); PAS_DEBUG2("Request::appendBody OldSize[%d] NewSize[%d]", pRawBody->size(), newSize); // 버퍼 사이즈 변경(resize) ACE_Message_Block* pTmpBlock = pRawBody; pRawBody = pMBManager->alloc(newSize); if(pRawBody == NULL) { PAS_ERROR("Request::appendBody, AllocMessageBlock fail!!"); return -1; } // 임시 버퍼로 부터 데이터 복원 int resultCopy = pRawBody->copy(pTmpBlock->rd_ptr(), pTmpBlock->length()); if(resultCopy < 0) { PAS_ERROR("Response::appendBody >> 기존 데이터 복사 실패"); } // 임시 버퍼 삭제 pMBManager->free(pTmpBlock); } // append int resultCopy = pRawBody->copy(buf, bufSize); if(resultCopy < 0) { PAS_ERROR("Response::appendBody >> 신규 데이터 복사 실패"); return -1; } // re-calculate bodyLeng = pRawBody->length(); return 0; }
int JAWS_Parse_Headers::parse_header_value (JAWS_Header_Info *info, ACE_Message_Block &mb) { // break --> return 1; // continue --> return 0; char *q = mb.rd_ptr (); if (info->last_header_data () == 0) { // Ignoring this header (it is too long or something). q = this->skipset ("\n", mb.rd_ptr (), mb.wr_ptr ()); if (q == mb.wr_ptr ()) { info->end_of_line (0); mb.rd_ptr (q); // Move the rd_ptr back one character if the last thing we // see is a carriage return. Assert: wr_ptr > rd_ptr. if (q[-1] == '\r') mb.rd_ptr (q-1); return 1; } if (*q == '\0') { // We are in the middle of binary data. Get out! mb.rd_ptr (q); info->end_of_line (1); info->end_of_headers (1); return 1; } // Move past the newline, set the end of line flag if (*q == '\n') { info->end_of_line (1); q++; } mb.rd_ptr (q); return 0; } else { if (info->end_of_line ()) { // Skip over leading linear white space q = this->skipcset (" \t", mb.rd_ptr (), mb.wr_ptr ()); if (q == mb.wr_ptr ()) { // need more input info->end_of_line (1); mb.rd_ptr (q-1); return 1; } if (*q != '\n') info->append_last_header_value (' '); } // Append to last header value character by character while (q < mb.wr_ptr ()) { if (*q == '\n') break; info->append_last_header_value (*q); q++; } // Need more input if (q == mb.wr_ptr ()) { mb.rd_ptr (q); info->end_of_line (0); return 1; } // Reached a newline if (*q == '\n') { // Reduce by one character if line discipline is "\r\n" if (info->append_last_header_value () == '\r') info->reduce_last_header_value (); // Move past newline, set end of line flag mb.rd_ptr (q+1); info->end_of_line (1); return 0; } } // NOT REACHED return 1; }
/** SSL 처리용 -- http 분석 없이 그냥 복사 */ int Request::recvRaw(ACE_Message_Block &recvBuf) { setBody(recvBuf.rd_ptr(), recvBuf.length()); return 0; }
ACE_Message_Block * ACE_Message_Block::clone (Message_Flags mask) const { ACE_TRACE ("ACE_Message_Block::clone"); // Get a pointer to a "cloned" <ACE_Data_Block> (will copy the // values rather than increment the reference count). ACE_Data_Block *db = this->data_block ()->clone (mask); if (db == 0) return 0; ACE_Message_Block *nb = 0; if(message_block_allocator_ == 0) { ACE_NEW_RETURN (nb, ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, // execution time ACE_DEADLINE_TIME, // absolute time to deadline // Get a pointer to a // "duplicated" <ACE_Data_Block> // (will simply increment the // reference count). db, db->data_block_allocator (), this->message_block_allocator_), 0); } else { // This is the ACE_NEW_MALLOC macro with the return check removed. // We need to do it this way because if it fails we need to release // the cloned data block that was created above. If we used // ACE_NEW_MALLOC_RETURN, there would be a memory leak because the // above db pointer would be left dangling. nb = static_cast<ACE_Message_Block*> (message_block_allocator_->malloc (sizeof (ACE_Message_Block))); if(nb != 0) new (nb) ACE_Message_Block (0, // size ACE_Message_Type (0), // type 0, // cont 0, // data 0, // allocator 0, // locking strategy 0, // flags this->priority_, // priority ACE_EXECUTION_TIME, // execution time ACE_DEADLINE_TIME, // absolute time to deadline db, db->data_block_allocator (), this->message_block_allocator_); } if (nb == 0) { db->release (); return 0; } // Set the read and write pointers in the new <Message_Block> to the // same relative offset as in the existing <Message_Block>. nb->rd_ptr (this->rd_ptr_); nb->wr_ptr (this->wr_ptr_); // Clone all the continuation messages if necessary. if (this->cont () != 0 && (nb->cont_ = this->cont ()->clone (mask)) == 0) { nb->release (); return 0; } return nb; }
int Thread_Pool::test_queue_deactivation_shutdown (void) { if (this->open () == -1) return -1; ACE_Message_Block *mb = 0; // Run the main loop that generates messages and enqueues them into // the pool of threads managed by <ACE_Task>. for (size_t count = 0; ; count++) { ssize_t n = 0; // Allocate a new message. ACE_NEW_RETURN (mb, ACE_Message_Block (BUFSIZ, ACE_Message_Block::MB_DATA, 0, 0, 0, &this->lock_adapter_), -1); if (manual) { #if !defined (ACE_HAS_WINCE) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) enter a new message for ") ACE_TEXT ("the task pool..."))); n = ACE_OS::read (ACE_STDIN, mb->wr_ptr (), mb->size ()); #endif // ACE_HAS_WINCE } else { static size_t count = 0; ACE_OS::sprintf (reinterpret_cast<ACE_TCHAR *> (mb->wr_ptr ()), ACE_SIZE_T_FORMAT_SPECIFIER, count); n = ACE_OS::strlen (mb->rd_ptr ()); if (count == n_iterations) n = 1; // Indicate that we need to shut down. else count++; if (count == 0 || (count % 20 == 0)) ACE_OS::sleep (1); } if (n > 1) { // Send a normal message to the waiting threads and continue // producing. mb->wr_ptr (n * sizeof (ACE_TCHAR)); // Pass the message to the Thread_Pool. if (this->put (mb) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT (" (%t) %p\n"), ACE_TEXT ("put"))); } else { // Release the <Message_Block> since we're shutting down and // don't need it anymore. mb->release (); // Deactivate the message queue and return. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n(%t) deactivating queue for %d threads, ") ACE_TEXT ("dump of task:\n"), this->thr_count ())); this->dump (); // Deactivate the queue. return this->msg_queue ()->deactivate (); } } }
int LoopDeviceSvcHandler::RecvRequest(int *pRet,KSG_GW_PACK_t* gw_pack) { KSG_GW_PACK_t* req; request_pack* pack; int ret; ACE_Message_Block * mb = NULL; ACE_Time_Value tv(5); tv += ACE_OS::gettimeofday(); ret = this->getq(mb,&tv); ACE_ASSERT((ret != -1)); ACE_DEBUG((LM_DEBUG,"处理业务请求")); if(!mb) { ACE_DEBUG((LM_ERROR,"未从消息队列中获取数据包[%d]",ret)); return -1; } req = (KSG_GW_PACK_t*)mb->rd_ptr(); if(UnPackData(req)) { ACE_DEBUG((LM_DEBUG,"解压数据包失败")); return -1; } memcpy(gw_pack,req,sizeof(KSG_GW_PACK_t)); ret = -1; ACE_DEBUG((LM_DEBUG,"处理第[%d]个数据包,后续包标志[%d]",req->pack_index ,req->next_pack)); if((pack = (request_pack*)ACE_OS::malloc(sizeof(request_pack))) == NULL) { ACE_ERROR_RETURN((LM_ERROR,"申请内存失败"),-1); } try { ACE_OS::memset(pack,0,sizeof pack); pack->datalen = req->length; memcpy(pack->data,req->data,pack->datalen); *pRet = KSGLoopDeviceListenScheduler::_s_interface.ProcessRequest( req->func_no,pack); if(pack->outdatalen >= sizeof(pack->outdata)) { ACE_DEBUG((LM_ERROR,"业务层返回数据包错误")); *pRet = KSG_LI_INTERNAL_ERROR; } else if(*pRet != 0) { pack->outdata[pack->outdatalen] = 0; ACE_DEBUG((LM_DEBUG,"处理请求失败[%d][%s]",*pRet,pack->outdata)); } // 应答 if(SendResponse(*pRet,req,pack)) { ACE_DEBUG((LM_ERROR,"发送应答数据包失败")); } else ret = 0; } catch(...) { ACE_DEBUG((LM_ERROR,"请求处理异常!!!")); // } mb->release(); ACE_OS::free(pack); return ret; }
int Thread_Pool::test_empty_message_shutdown (void) { if (this->open () == -1) return -1; ACE_Message_Block *mb = 0; // Run the main loop that generates messages and enqueues them into // the pool of threads managed by <ACE_Task>. for (size_t count = 0; ; count++) { ssize_t n = 0; // Allocate a new message. ACE_NEW_RETURN (mb, ACE_Message_Block (BUFSIZ, ACE_Message_Block::MB_DATA, 0, 0, 0, &this->lock_adapter_), -1); if (manual) { #if !defined (ACE_HAS_WINCE) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) enter a new message for ") ACE_TEXT ("the task pool..."))); n = ACE_OS::read (ACE_STDIN, mb->wr_ptr (), mb->size ()); #endif // ACE_HAS_WINCE } else { static size_t count = 0; ACE_OS::sprintf (reinterpret_cast<ACE_TCHAR *> (mb->wr_ptr ()), ACE_SIZE_T_FORMAT_SPECIFIER, count); n = ACE_OS::strlen (mb->rd_ptr ()); if (count == n_iterations) n = 1; // Indicate that we need to shut down. else count++; if (count == 0 || (count % 20 == 0)) ACE_OS::sleep (1); } if (n > 1) { // Send a normal message to the waiting threads and continue // producing. mb->wr_ptr (n * sizeof (ACE_TCHAR)); // Pass the message to the Thread_Pool. if (this->put (mb) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT (" (%t) %p\n"), ACE_TEXT ("put"))); } else { // Send a shutdown message to the waiting threads and return. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n(%t) sending shutdown message to %d threads, ") ACE_TEXT ("dump of task:\n"), this->thr_count ())); this->dump (); size_t i = 0; // Enqueue an empty message to flag each consumer thread to // inform it to shutdown. for (i = this->thr_count (); i > 0; i--) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) end of input, ") ACE_TEXT ("enqueueing \"empty\" message %d\n"), i)); // Note the use of reference counting to avoid copying // the message contents. ACE_Message_Block *dup = mb->duplicate (); if (this->put (dup) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT (" (%t) %p\n"), ACE_TEXT ("put"))); } mb->release (); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n(%t) end loop, dump of task:\n"))); this->dump (); return 0; } } }
bool CReactorUDPHander::SendMessage(const char* pMessage, uint32 u4Len, const char* szIP, int nPort, bool blHead, uint16 u2CommandID) { ACE_hrtime_t m_tvBegin = ACE_OS::gethrtime(); ACE_INET_Addr AddrRemote; int nErr = AddrRemote.set(nPort, szIP); if(nErr != 0) { OUR_DEBUG((LM_INFO, "[CProactorUDPHandler::SendMessage]set_address error[%d].\n", errno)); SAFE_DELETE_ARRAY(pMessage); return false; } //如果需要拼接包头,则拼接包头 if(blHead == true) { CPacketParse PacketParse; ACE_Message_Block* pMbData = NULL; uint32 u4SendLength = App_PacketParseLoader::instance()->GetPacketParseInfo()->Make_Send_Packet_Length(0, u4Len, u2CommandID); pMbData = App_MessageBlockManager::instance()->Create(u4SendLength); if(NULL == pMbData) { SAFE_DELETE(pMessage); return false; } App_PacketParseLoader::instance()->GetPacketParseInfo()->Make_Send_Packet(0, pMessage, u4Len, pMbData, u2CommandID); int nSize = (int)m_skRemote.send(pMbData->rd_ptr(), pMbData->length(), AddrRemote); if((uint32)nSize == u4Len) { m_atvOutput = ACE_OS::gettimeofday(); m_u4SendSize += u4Len; m_u4SendPacketCount++; SAFE_DELETE_ARRAY(pMessage); //统计发送信息 uint32 u4Cost = (uint32)(ACE_OS::gethrtime() - m_tvBegin); m_CommandAccount.SaveCommandData(u2CommandID, u4Cost, PACKET_UDP, (uint32)pMbData->length(), u4Len, COMMAND_TYPE_OUT); //释放发送体 pMbData->release(); return true; } else { OUR_DEBUG((LM_ERROR, "[CProactorUDPHandler::SendMessage]send error(%d).\n", errno)); SAFE_DELETE_ARRAY(pMessage); //释放发送体 pMbData->release(); return false; } } else { int nSize = (int)m_skRemote.send(pMessage, u4Len, AddrRemote); if((uint32)nSize == u4Len) { m_atvOutput = ACE_OS::gettimeofday(); m_u4SendSize += u4Len; m_u4SendPacketCount++; SAFE_DELETE_ARRAY(pMessage); //统计发送信息 uint32 u4Cost = (uint32)(ACE_OS::gethrtime() - m_tvBegin); m_CommandAccount.SaveCommandData(u2CommandID, u4Cost, PACKET_UDP, u4Len, u4Len, COMMAND_TYPE_OUT); return true; } else { OUR_DEBUG((LM_ERROR, "[CProactorUDPHandler::SendMessage]send error(%d).\n", errno)); SAFE_DELETE_ARRAY(pMessage); return false; } } }
int Response::appendBody(const char* buf, const size_t bufSize) { ACE_ASSERT(buf != NULL); ACE_ASSERT(bufSize > 0); if (pRawBody == NULL) { // 아래를 안해 주면 대용량 처리할 때 문제가 된다. // 메모리 할당/해제 회수를 줄일려면 아래를 실행 해 주어야 한다. size_t newSize = std::max(bufSize, contentLength); // chunk 인 경우 빨리 버퍼를 충분히 할당하기 위해. (2007.1.3) // 빈번한 버퍼 크기 확장을 막기 위해, 초기 최소 사이즈를 제한 newSize = std::max(newSize, (size_t)BODY_BUF_INIT_SIZE); pRawBody = pMBManager->alloc(newSize); if(pRawBody == NULL) { PAS_ERROR("Response::appendBody, AllocMessageBlock fail!!"); return -1; } // reset buf expand counter bodyBufferExpandCount = 0; } ACE_ASSERT(pRawBody != NULL); // 버퍼 크기 확장 if(pRawBody->space() < bufSize) { // 빈번한 버퍼 크기 확장을 막기 위해 size_t newSize = std::max((pRawBody->size() + (bufSize * 2)), (pRawBody->size() * 2)); PAS_DEBUG2("Response::appendBody OldSize[%d] NewSize[%d]", pRawBody->size(), newSize); // 버퍼 사이즈 변경(resize) ACE_Message_Block* pTmpBlock = pRawBody; pRawBody = pMBManager->alloc(newSize); if(pRawBody == NULL) { PAS_ERROR("Response::appendBody, AllocMessageBlock fail!!"); return -1; } // 기존 버퍼로 부터 데이터 복원 int resultCopy = pRawBody->copy(pTmpBlock->rd_ptr(), pTmpBlock->length()); if(resultCopy < 0) { PAS_ERROR("Response::appendBody >> 기존 데이터 복사 실패"); } // 임시 버퍼 삭제 pMBManager->free(pTmpBlock); bodyBufferExpandCount++; } // append int resultCopy = pRawBody->copy(buf, bufSize); if(resultCopy < 0) { PAS_ERROR("Response::appendBody >> 신규 데이터 복사 실패"); return -1; } return 0; }
int Peer_Handler::transmit_stdin (void) { // If return value is -1, then first_time_ must be reset to 1. int result = 0; if (this->connection_id_ != -1) { ACE_Message_Block *mb = 0; ACE_NEW_RETURN (mb, ACE_Message_Block (sizeof (Event)), -1); // Cast the message block payload into an <Event> pointer. Event *event = (Event *) mb->rd_ptr (); ssize_t n = ACE_OS::read (ACE_STDIN, event->data_, sizeof event->data_); switch (n) { case 0: ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("stdin closing down\n"))); // Take stdin out of the ACE_Reactor so we stop trying to // send events. ACE_Reactor::instance ()->remove_handler (ACE_STDIN, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::READ_MASK); mb->release (); result = 0; // break; /* NOTREACHED */ case -1: mb->release (); ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("read"))); result = 0; // break; /* NOTREACHED */ default: // Do not return directly, save the return value. result = this->transmit (mb, n, ROUTING_EVENT); break; /* NOTREACHED */ } // Do not return at here, but at exit of function. /*return 0;*/ } else { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Must transmit over an opened channel.\n"))); result = -1; // Save return value at here, return at exit of function. } // If transmit error, the stdin-thread will be cancelled, so should // reset first_time_ to 1, which will register_stdin_handler again. if (result == -1) first_time_ = 1; return result; }
virtual int svc () { const size_t FileReadSize = 8 * 1024; ACE_Message_Block mblk (FileReadSize); for (;; mblk.crunch ()) { // Read as much as will fit in the message block. ssize_t bytes_read = logfile_.recv (mblk.wr_ptr (), mblk.space ()); if (bytes_read <= 0) break; mblk.wr_ptr (static_cast<size_t> (bytes_read)); // We have a bunch of data from the log file. The data is // arranged like so: // hostname\0 // CDR-encoded log record // So, first we scan for the end of the host name, then // initialize another ACE_Message_Block aligned for CDR // demarshaling and copy the remainder of the block into it. We // can't use duplicate() because we need to be sure the data // pointer is aligned properly for CDR demarshaling. If at any // point, there's not enough data left in the message block to // extract what's needed, crunch the block to move all remaining // data to the beginning and read more from the file. for (;;) { size_t name_len = ACE_OS::strnlen (mblk.rd_ptr (), mblk.length ()); if (name_len == mblk.length ()) break; char *name_p = mblk.rd_ptr (); ACE_Message_Block *rec, *head, *temp; ACE_NEW_RETURN (head, ACE_Message_Block (name_len, MB_CLIENT), 0); head->copy (name_p, name_len); mblk.rd_ptr (name_len + 1); // Skip nul also size_t need = mblk.length () + ACE_CDR::MAX_ALIGNMENT; ACE_NEW_RETURN (rec, ACE_Message_Block (need), 0); ACE_CDR::mb_align (rec); rec->copy (mblk.rd_ptr (), mblk.length ()); // Now rec contains the remaining data we've read so far from // the file. Create an ACE_InputCDR to start demarshaling the // log record, header first to find the length, then the data. // Since the ACE_InputCDR constructor increases the reference count // on rec, we release it upon return to prevent leaks. // The cdr 'read' methods return 0 on failure, 1 on success. ACE_InputCDR cdr (rec); rec->release (); ACE_CDR::Boolean byte_order; if (!cdr.read_boolean (byte_order)) { head->release (); rec->release (); break; } cdr.reset_byte_order (byte_order); // Now read the length of the record. From there, we'll know // if rec contains the complete record or not. ACE_CDR::ULong length; if (!cdr.read_ulong (length)) { head->release (); mblk.rd_ptr (name_p); break; } if (length > cdr.length ()) { head->release (); mblk.rd_ptr (name_p); break; } // The complete record is in rec... grab all the fields into // separate, chained message blocks. ACE_NEW_RETURN (temp, ACE_Message_Block (length, MB_TEXT), 0); ACE_NEW_RETURN (temp, ACE_Message_Block (2 * sizeof (ACE_CDR::Long), MB_TIME, temp), 0); ACE_NEW_RETURN (temp, ACE_Message_Block (sizeof (ACE_CDR::Long), MB_PID, temp), 0); ACE_NEW_RETURN (temp, ACE_Message_Block (sizeof (ACE_CDR::Long), MB_TYPE, temp), 0); head->cont (temp); // Extract the type ACE_CDR::Long *lp; lp = reinterpret_cast<ACE_CDR::Long*> (temp->wr_ptr ()); cdr >> *lp; temp->wr_ptr (sizeof (ACE_CDR::Long)); temp = temp->cont (); // Extract the pid lp = reinterpret_cast<ACE_CDR::Long*> (temp->wr_ptr ()); cdr >> *lp; temp->wr_ptr (sizeof (ACE_CDR::Long)); temp = temp->cont (); // Extract the timestamp (2 Longs) lp = reinterpret_cast<ACE_CDR::Long*> (temp->wr_ptr ()); cdr >> *lp; ++lp; cdr >> *lp; temp->wr_ptr (2 * sizeof (ACE_CDR::Long)); temp = temp->cont (); // Demarshal the length of the message text, then demarshal // the text into the block. ACE_CDR::ULong text_len; cdr >> text_len; cdr.read_char_array (temp->wr_ptr (), text_len); temp->wr_ptr (text_len); // Forward the whole lot to the next module. if (put_next (head) == -1) break; // Move the file-content block's read pointer up past whatever // was just processed. Although the mblk's rd_ptr has not been // moved, cdr's has. Therefore, use its length() to determine // how much is left. mblk.rd_ptr (mblk.length () - cdr.length ()); } } // Now that the file is done, send a block down the stream to tell // the other modules to stop. ACE_Message_Block *stop; ACE_NEW_RETURN (stop, ACE_Message_Block (0, ACE_Message_Block::MB_STOP), 0); put_next (stop); return 0; }
int HDCCUSvrHandler::svc() { #define MES_DATA_HEAD_LEN 2 ACE_DEBUG((LM_DEBUG,"ACE 打开连接............")); ACE_Message_Block * mb = NULL; ACE_Time_Value tv(5); if (this->getq(mb,&tv) == -1) return -1; HD8583STRUCT req; HD8583STRUCT resp; MESSAGETYPE msg_type; char * buffer = mb->rd_ptr(); int len = 0; // 数据段长度超过允许范围,忽略请求 if(UnPackResponseStruct(req,&msg_type,buffer,mb->length()) != 0) { ACE_ERROR((LM_ERROR,"数据包不合法")); mb->release(); return -1; } ACE_HEX_DUMP((LM_DEBUG,mb->rd_ptr(),mb->length())); try { HDResponseHandler* handler = HDCCUProcessUnits::Instance().Create(msg_type); if(handler) { resp.Init(); int result = handler->DoResponse(req,resp,peer().get_handle()); if(result > 0) { // send back mb->reset(); buffer = mb->wr_ptr(); len = (int)PackRequestStruct(resp,msg_type,buffer,mb->size()); mb->wr_ptr(len); ACE_HEX_DUMP((LM_DEBUG,buffer,mb->length())); ACE_DEBUG((LM_DEBUG,"数据包长度[%d]",mb->length())); if(peer().send_n(mb->rd_ptr(),mb->length()) <=0 ) { ACE_DEBUG((LM_ERROR,"发送应答包失败")); } } else if(result == 0) { // OK ACE_DEBUG((LM_DEBUG,"处理成功")); } else { // error ACE_DEBUG((LM_ERROR,"处理请求失败,返回码[%d]",result)); } } else { ACE_ERROR((LM_ERROR,"不能处理请求代码[%c]",msg_type)); } } catch(...) { // 捕获所有的异常 ACE_ERROR((LM_ERROR,"处理请求异常,请求代码[%02x]",msg_type)); } mb->release(); return 0; }
int Peer_Handler::handle_input (ACE_HANDLE h) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) input arrived on handle %d\n"), h)); ACE_Message_Block *db; ACE_NEW_RETURN (db, ACE_Message_Block (BUFSIZ), -1); ACE_Message_Block *hb = new ACE_Message_Block (sizeof (ROUTING_KEY), ACE_Message_Block::MB_PROTO, db); // Check for memory failures. if (hb == 0) { db->release (); errno = ENOMEM; return -1; } ssize_t n = this->peer ().recv (db->rd_ptr (), db->size ()); if (n == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p"), ACE_TEXT ("recv failed")), -1); else if (n == 0) // Client has closed down the connection. { if (this->peer_router_context_->unbind_peer (this->get_handle ()) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p"), ACE_TEXT ("unbind failed")), -1); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) shutting down handle %d\n"), h)); // Instruct the <ACE_Reactor> to deregister us by returning -1. return -1; } else { // Transform incoming buffer into an <ACE_Message_Block>. // First, increment the write pointer to the end of the newly // read data block. db->wr_ptr (n); // Second, copy the "address" into the header block. Note that // for this implementation the HANDLE we receive the message on // is considered the "address." A "real" application would want // to do something more sophisticated. *(ACE_HANDLE *) hb->rd_ptr () = this->get_handle (); // Third, update the write pointer in the header block. hb->wr_ptr (sizeof (ACE_HANDLE)); // Finally, pass the message through the stream. Note that we // use <Task::put> here because this gives the method at *our* // level in the stream a chance to do something with the message // before it is sent up the other side. For instance, if we // receive messages in the <Supplier_Router>, it will just call // <put_next> and send them up the stream to the // <Consumer_Router> (which broadcasts them to consumers). // However, if we receive messages in the <Consumer_Router>, it // could reply to the Consumer with an error since it's not // correct for Consumers to send messages (we don't do this in // the current implementation, but it could be done in a "real" // application). if (this->peer_router_context_->peer_router ()->put (hb) == -1) return -1; else return 0; } }
void Reciever::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result) { ACE_Message_Block &mb = result.message_block (); //if the connection is failed£¬release the connection resource to the client if (!result.success () || result.bytes_transferred () == 0) { mb.release (); delete this; return; } ACE_OS::printf("In read data\n"); dispatcher = new MessageDispatcher(); dispatcher->dispatchMessage(mb); handler = new MessageHandler(); ACE_UINT32 cmd = dispatcher->getCmd(); ACE_Message_Block* smb; //case CONNECT_SERVER //------------------------------------------------------------------------// if(cmd == COM::CONNECT_SERVER) { ACE_OS::printf("In CONNECT_SERVER\n"); pair<ACE_UINT16,ACE_UINT16> randomPos = handler->handleConnectionSever(dispatcher->getIP(),dispatcher->getPort()); if(randomPos.first != 0 && randomPos.second != 0) { MessageConstructor::getInstance()->setAddress(this->local_address); smb = MessageConstructor::getInstance()->createConnectionAck(randomPos.first,randomPos.second,DEFAULT_AOI_RADIUS); } } //case GET_SCENE_DATA //------------------------------------------------------------------------// else if(cmd == COM::GET_SCENE_DATA) { } //case CONNECT_FAIL_REPORT //------------------------------------------------------------------------// //case CLIENT_MOVE //------------------------------------------------------------------------// //case CLIENT_QUIT //------------------------------------------------------------------------// //case MORE_COMMAND //------------------------------------------------------------------------// dispatcher->setMB_NULL(); mb.release(); ACE_OS::printf("\nMMB data:%s\n",smb->rd_ptr()); if (this->writer_.write(*smb,smb->length()) != 0) { ACE_OS::printf("Write Failed!"); //MessageConstructor::getInstance()->setMB_NULL(); smb->release(); delete this; return; } MessageConstructor::getInstance()->setMB_NULL(); if(handler != NULL) delete handler; if(dispatcher != NULL) delete dispatcher; smb->release(); }
int Task::svc (void) { this->barrier_.wait (); ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %d\n", (void *) this, ACE_Thread::self ())); ACE_Message_Block *message; for (;;) { if (this->getq (message) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); if (message->msg_type () == ACE_Message_Block::MB_HANGUP) { this->putq (message); break; } const char *cp = message->rd_ptr (); // Don't forget to skip the NULL we inserted message->rd_ptr (ACE_OS::strlen (cp) + 1); ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block 0x%x contains (%s)\n", (void *) message, cp)); /* Create a Data object into which we can extract the message block contents. */ Data data; /* Use the rd_ptr() to access the message block data. Note that we've already moved it past the text string in the block. */ ACE_OS::memmove ((char *) &data, message->rd_ptr (), sizeof (data)); message->rd_ptr (sizeof (data)); // Move the rd_ptr() beyond the data. /* Invoke a couple of method calls on the object we constructed. */ data.who_am_i (); data.what_am_i (); /* An alternate approach: Data * data; data = (Data *)message->rd_ptr(); data->who_am_i(); data->what_am_i(); message->rd_ptr(sizeof(Data)); Even though this cuts down on the number of copies & constructions, I'm not real fond of it. You can get into trouble in a hurry by treating memory blocks as multiple data types... */ ACE_OS::sleep (ACE_Time_Value (0, 5000)); message->release (); } return 0; }