1 #include "ace/Message_Block.h"
2 #include "ace/SOCK_Stream.h"
3 #include "ace/Filecache.h"
4 #include "ace/OS_NS_string.h"
5 #include "ace/OS_NS_unistd.h"
6 #include "ace/OS_NS_sys_uio.h"
7 #include "ace/OS_NS_sys_socket.h"
8 #include "ace/Min_Max.h"
10 #include "JAWS/Data_Block.h"
11 #include "JAWS/Policy.h"
12 #include "JAWS/Jaws_IO.h"
13 #include "JAWS/IO_Handler.h"
14 #include "JAWS/IO_Acceptor.h"
15 #include "JAWS/Filecache.h"
17 #include "ace/Asynch_IO.h" //for ACE_Asynch_Write_Stream
19 // #include "HTTP_Helpers.h"
23 : handle_ (ACE_INVALID_HANDLE
),
42 JAWS_IO::handle (ACE_HANDLE handle
)
44 this->handle_
= handle
;
48 JAWS_IO::handler (JAWS_IO_Handler
*handler
)
50 this->handler_
= handler
;
54 JAWS_IO::acceptor (JAWS_IO_Acceptor
*acceptor
)
56 this->acceptor_
= acceptor
;
60 JAWS_Synch_IO::JAWS_Synch_IO ()
62 this->acceptor_
= JAWS_IO_Synch_Acceptor_Singleton::instance ();
65 JAWS_Synch_IO::~JAWS_Synch_IO ()
67 if (this->handle_
!= ACE_INVALID_HANDLE
)
68 ACE_OS::closesocket (this->handle_
);
72 JAWS_Synch_IO::accept (JAWS_IO_Handler
*ioh
,
76 ACE_SOCK_Stream new_stream
;
77 new_stream
.set_handle (ACE_INVALID_HANDLE
);
78 if (this->acceptor_
->accept (new_stream
) == -1)
81 ioh
->accept_complete (new_stream
.get_handle ());
85 JAWS_Synch_IO::read (JAWS_IO_Handler
*ioh
,
86 ACE_Message_Block
*mb
,
89 JAWS_TRACE ("JAWS_Synch_IO::read");
91 ACE_SOCK_Stream stream
;
93 stream
.set_handle (ioh
->handle ());
94 int result
= stream
.recv (mb
->wr_ptr (), size
);
100 JAWS_TRACE ("JAWS_Synch_IO::read success");
102 ioh
->read_complete (mb
);
107 JAWS_Synch_IO::receive_file (JAWS_IO_Handler
*ioh
,
108 const char *filename
,
110 unsigned int initial_data_length
,
111 unsigned int entire_length
)
113 ACE_Filecache_Handle
handle (filename
,
114 (int) entire_length
);
116 int result
= handle
.error ();
118 if (result
== ACE_Filecache_Handle::ACE_SUCCESS
)
120 ACE_SOCK_Stream stream
;
121 stream
.set_handle (ioh
->handle ());
123 int bytes_to_memcpy
= ACE_MIN (entire_length
, initial_data_length
);
124 ACE_OS::memcpy (handle
.address (), initial_data
, bytes_to_memcpy
);
126 int bytes_to_read
= entire_length
- bytes_to_memcpy
;
128 int bytes
= stream
.recv_n ((char *)
129 handle
.address () + initial_data_length
,
131 if (bytes
== bytes_to_read
)
132 ioh
->receive_file_complete ();
137 if (result
!= ACE_Filecache_Handle::ACE_SUCCESS
)
138 ioh
->receive_file_error (result
);
142 JAWS_Synch_IO::transmit_file (JAWS_IO_Handler
*ioh
,
145 unsigned int header_size
,
147 unsigned int trailer_size
)
151 if (handle
!= ACE_INVALID_HANDLE
)
153 ACE_SOCK_Stream stream
;
154 stream
.set_handle (ioh
->handle ());
156 if ((unsigned long) stream
.send_n (header
, header_size
) < header_size
)
167 count
= ACE_OS::read (handle
, buf
, sizeof (buf
));
171 if (stream
.send_n (buf
, count
) < count
)
178 if ((unsigned long) stream
.send_n (trailer
, trailer_size
)
187 ioh
->transmit_file_complete ();
189 ioh
->transmit_file_error (result
);
193 JAWS_Synch_IO::transmit_file (JAWS_IO_Handler
*ioh
,
194 const char *filename
,
196 unsigned int header_size
,
198 unsigned int trailer_size
)
204 ioh
->transmit_file_error (-1);
208 JAWS_Cached_FILE
cf (filename
);
210 if (cf
.file ()->get_handle () != ACE_INVALID_HANDLE
213 #if defined (ACE_JAWS_BASELINE) || defined (ACE_WIN32)
215 cf
.file ()->get_info (info
);
217 if (cf
.file ()->get_info (info
) == 0 && info
.size_
> 0)
219 ACE_SOCK_Stream stream
;
220 stream
.set_handle (ioh
->handle ());
221 if (((u_long
) stream
.send_n (header
, header_size
) == header_size
)
222 && (stream
.send_n (cf
.mmap ()->addr (), info
.size_
)
224 && ((u_long
) stream
.send_n (trailer
, trailer_size
)
227 ioh
->transmit_file_complete ();
240 // Attempting to use writev
246 iov
[iovcnt
].iov_base
= const_cast<char*> (header
);
247 iov
[iovcnt
].iov_len
= header_size
;
253 if (cf
.file ()->get_info (info
) == 0 && info
.size_
> 0)
255 iov
[iovcnt
].iov_base
= (char *) cf
.mmap ()->addr ();
256 iov
[iovcnt
].iov_len
= info
.size_
;
259 if (trailer_size
> 0)
261 iov
[iovcnt
].iov_base
= const_cast<char*> (trailer
);
262 iov
[iovcnt
].iov_len
= trailer_size
;
265 if (ACE_OS::writev (ioh
->handle (), iov
, iovcnt
) < 0)
271 ioh
->transmit_file_complete ();
274 #endif /* ACE_JAWS_BASELINE */
276 else if (cf
.file ()->get_handle () != ACE_INVALID_HANDLE
279 this->transmit_file (ioh
,
280 cf
.file ()->get_handle (),
282 trailer
, trailer_size
);
292 ioh
->transmit_file_error (result
);
297 JAWS_Synch_IO::send_confirmation_message (JAWS_IO_Handler
*ioh
,
301 this->send_message (ioh
, buffer
, length
);
302 ioh
->confirmation_message_complete ();
306 JAWS_Synch_IO::send_error_message (JAWS_IO_Handler
*ioh
,
310 this->send_message (ioh
, buffer
, length
);
311 ioh
->error_message_complete ();
315 JAWS_Synch_IO::send_message (JAWS_IO_Handler
*ioh
,
319 ACE_SOCK_Stream stream
;
320 stream
.set_handle (ioh
->handle ());
321 stream
.send_n (buffer
, length
);
324 // This only works on asynch I/O-capable systems.
325 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
327 JAWS_Asynch_IO::JAWS_Asynch_IO ()
331 JAWS_Asynch_IO::~JAWS_Asynch_IO ()
333 if (this->handle_
!= ACE_INVALID_HANDLE
)
334 ACE_OS::closesocket (this->handle_
);
338 JAWS_Asynch_IO::accept (JAWS_IO_Handler
*ioh
,
342 JAWS_TRACE ("JAWS_Asynch_IO::accept");
346 JAWS_Data_Block
*db
= ioh
->message_block ();
347 //ACE_HANDLE listen_handle = db->policy ()->acceptor ()->get_handle ();
349 //JAWS_Asynch_IO_Handler *aioh =
350 // dynamic_cast<JAWS_Asynch_IO_Handler *> (ioh);
352 size_t bytes_to_read
= JAWS_Data_Block::JAWS_DATA_BLOCK_SIZE
;
354 if (db
->policy ()->acceptor ()->accept (bytes_to_read
, ioh
) == -1)
355 ioh
->accept_error ();
359 JAWS_Asynch_IO::read (JAWS_IO_Handler
*ioh
,
360 ACE_Message_Block
* mb
,
363 JAWS_TRACE ("JAWS_Asynch_IO::read");
367 JAWS_Asynch_IO_Handler
*aioh
=
368 dynamic_cast<JAWS_Asynch_IO_Handler
*> (ioh
);
370 ACE_Asynch_Read_Stream ar
;
372 if (ar
.open (*(aioh
->handler ()), aioh
->handle ()) == -1
373 || ar
.read (*mb
, size
) == -1)
378 JAWS_Asynch_IO::receive_file (JAWS_IO_Handler
*ioh
,
379 const char *filename
,
381 unsigned int initial_data_length
,
382 unsigned int entire_length
)
384 JAWS_TRACE ("JAWS_Asynch_IO::receive_file");
388 JAWS_Asynch_IO_Handler
*aioh
=
389 dynamic_cast<JAWS_Asynch_IO_Handler
*> (ioh
);
391 ACE_Message_Block
*mb
= 0;
392 ACE_Filecache_Handle
*handle
;
394 ACE_NEW (handle
, ACE_Filecache_Handle (filename
, entire_length
, ACE_NOMAP
));
396 int result
= handle
->error ();
398 if (result
== ACE_Filecache_Handle::ACE_SUCCESS
)
400 ACE_OS::memcpy (handle
->address (),
402 initial_data_length
);
404 int bytes_to_read
= entire_length
- initial_data_length
;
406 ACE_NEW (mb
, ACE_Message_Block ((char *)handle
->address ()
407 + initial_data_length
, bytes_to_read
));
416 ACE_Asynch_Read_Stream ar
;
418 if (ar
.open (*(aioh
->handler ()), aioh
->handle ()) == -1
419 || ar
.read (*mb
, mb
->size () - mb
->length (), handle
) == -1)
424 if (result
!= ACE_Filecache_Handle::ACE_SUCCESS
)
426 this->handler_
->receive_file_error (result
);
433 JAWS_Asynch_IO::transmit_file (JAWS_IO_Handler
*ioh
,
436 unsigned int header_size
,
438 unsigned int trailer_size
)
440 JAWS_TRACE ("JAWS_Asynch_IO::transmit_file");
444 JAWS_Asynch_IO_Handler
*aioh
=
445 dynamic_cast<JAWS_Asynch_IO_Handler
*> (ioh
);
447 ACE_Asynch_Transmit_File::Header_And_Trailer
*header_and_trailer
= 0;
451 if (handle
!= ACE_INVALID_HANDLE
)
453 ACE_Message_Block
hdr_mb (header
, header_size
);
454 ACE_Message_Block
trl_mb (trailer
, trailer_size
);
457 new ACE_Asynch_Transmit_File::Header_And_Trailer (hdr_mb
.duplicate (),
462 ACE_Asynch_Transmit_File tf
;
464 if (tf
.open (*(aioh
->handler ()), aioh
->handle ()) == -1
465 || tf
.transmit_file (handle
, // file handle
466 header_and_trailer
, // header and trailer data
479 ioh
->transmit_file_error (result
);
480 delete header_and_trailer
;
485 JAWS_Asynch_IO::transmit_file (JAWS_IO_Handler
*ioh
,
486 const char *filename
,
488 unsigned int header_size
,
490 unsigned int trailer_size
)
494 JAWS_TRACE ("JAWS_Asynch_IO::transmit_file");
498 JAWS_Asynch_IO_Handler
*aioh
=
499 dynamic_cast<JAWS_Asynch_IO_Handler
*> (ioh
);
501 ACE_Asynch_Transmit_File::Header_And_Trailer
*header_and_trailer
= 0;
502 JAWS_Cached_FILE
*cf
= new JAWS_Cached_FILE (filename
);
504 if (cf
->file ()->get_handle () != ACE_INVALID_HANDLE
)
506 ACE_Message_Block
hdr_mb (header
, header_size
);
507 ACE_Message_Block
trl_mb (trailer
, trailer_size
);
509 header_and_trailer
= new ACE_Asynch_Transmit_File::Header_And_Trailer
510 (hdr_mb
.duplicate (), header_size
, trl_mb
.duplicate (), trailer_size
);
512 ACE_Asynch_Transmit_File tf
;
514 if (tf
.open (*(aioh
->handler ()), aioh
->handle ()) == -1
515 || tf
.transmit_file (cf
->file ()->get_handle (), // file handle
516 header_and_trailer
, // header and trailer data
529 ioh
->transmit_file_error (result
);
530 delete header_and_trailer
;
536 JAWS_Asynch_IO::send_confirmation_message (JAWS_IO_Handler
*ioh
,
540 this->send_message (ioh
, buffer
, length
, CONFIRMATION
);
544 JAWS_Asynch_IO::send_error_message (JAWS_IO_Handler
*ioh
,
548 this->send_message (ioh
, buffer
, length
, ERROR_MESSAGE
);
552 JAWS_Asynch_IO::send_message (JAWS_IO_Handler
*ioh
,
559 JAWS_Asynch_IO_Handler
*aioh
=
560 dynamic_cast<JAWS_Asynch_IO_Handler
*> (ioh
);
562 ACE_Message_Block
*mb
= 0;
563 ACE_NEW (mb
, ACE_Message_Block (buffer
, length
));
567 this->handler_
->error_message_complete ();
571 ACE_Asynch_Write_Stream aw
;
572 if (aw
.open (*(aioh
->handler ()), aioh
->handle ()) == -1
573 || aw
.write (*mb
, length
, (void *) static_cast<intptr_t> (act
)) == -1)
577 if (act
== CONFIRMATION
)
578 ioh
->confirmation_message_complete ();
580 ioh
->error_message_complete ();
585 JAWS_Asynch2_IO::accept (JAWS_IO_Handler
*,
591 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */