00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "RioError.h"
00020 #include "RioModule.h"
00021
00022
00023 #include <http_config.h>
00024 #include <http_log.h>
00025 #include <util_filter.h>
00026 #include <http_protocol.h>
00027
00028
00029 #include <stdlib.h>
00030
00031 #ifdef RIO_DEBUG2
00032
00033 #include <sys/syscall.h>
00034 #endif
00035
00036
00037 CRioModule::CRioModule( request_rec *Request )
00038 {
00039 int status;
00040
00041 m_Request = Request;
00042 m_Session = NULL;
00043 m_isSessionOpen = false;
00044 m_Stream = NULL;
00045 m_isStreamOpen = false;
00046 m_Object = NULL;
00047 m_isObjectOpen = false;
00048 m_CircularBuffer = NULL;
00049 m_RioBuffer = NULL;
00050 m_ApacheBuffer = NULL;
00051 m_ServerName = NULL;
00052 m_FileName = NULL;
00053 m_Started = false;
00054 m_ReadThread = 0;
00055 m_ThreadCanceled = false;
00056 m_StartFirstBlock = 0;
00057 m_EndPosition = 0;
00058 m_RioBlock = 0;
00059 m_SendBlock = 0;
00060 m_TotalBlocks = 0;
00061 m_isFirstBlock = false;
00062 m_isReadingFile = false;
00063 m_Access = RIO_SHARE_READ;
00064 m_BlockSize = 0;
00065 m_FragmentSize = 0;
00066
00067
00068 m_SystemStatus = 0;
00069 m_ApacheStatus = APR_SUCCESS;
00070 m_RioStatus = S_OK;
00071
00072 status = pthread_mutex_init( &m_ReadMutex, NULL );
00073 if( status < 0 )
00074 {
00075 m_SystemStatus = status;
00076
00077 #ifdef RIO_DEBUG2
00078 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00079 "Error initializing m_ReadMutex: %u (%s)",
00080 m_SystemStatus, strerror( m_SystemStatus ) );
00081 #endif
00082
00083 return;
00084 }
00085
00086 status = pthread_cond_init( &m_ReadCond, NULL );
00087 if( status < 0 )
00088 {
00089 m_SystemStatus = status;
00090
00091 #ifdef RIO_DEBUG2
00092 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00093 "Error initializing m_ReadCond: %u (%s)",
00094 m_SystemStatus, strerror( m_SystemStatus ) );
00095 #endif
00096
00097 return;
00098 }
00099
00100 status = pthread_cond_init( &m_ReadStarted, NULL );
00101 if( status < 0 )
00102 {
00103 m_SystemStatus = status;
00104
00105 #ifdef RIO_DEBUG2
00106 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00107 "Error initializing m_ReadStarted: %u (%s)",
00108 m_SystemStatus, strerror( m_SystemStatus ) );
00109 #endif
00110
00111 return;
00112 }
00113
00114 status = pthread_cond_init( &m_ThreadBlocked, NULL );
00115 if( status < 0 )
00116 {
00117 m_SystemStatus = status;
00118
00119 #ifdef RIO_DEBUG2
00120 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00121 "Error initializing m_ThreadBlocked: %u (%s)",
00122 m_SystemStatus, strerror( m_SystemStatus ) );
00123 #endif
00124
00125 return;
00126 }
00127
00128 status = pthread_mutex_init( &m_Mutex, NULL );
00129 if( status < 0 )
00130 {
00131 m_SystemStatus = status;
00132
00133 #ifdef RIO_DEBUG2
00134 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00135 "Error initializing m_Mutex: %u (%s)",
00136 m_SystemStatus, strerror( m_SystemStatus ) );
00137 #endif
00138
00139 return;
00140 }
00141 }
00142
00143
00144 CRioModule::~CRioModule()
00145 {
00146 int status;
00147
00148
00149 if( m_Started )
00150 Stop();
00151
00152 status = pthread_mutex_destroy( &m_ReadMutex );
00153 if( status < 0 )
00154 {
00155 #ifdef RIO_DEBUG2
00156 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00157 "Error destroying m_ReadMutex: %u (%s)", status,
00158 strerror( status ) );
00159 #endif
00160 }
00161
00162 status = pthread_cond_destroy( &m_ReadCond );
00163 if( status < 0 )
00164 {
00165 #ifdef RIO_DEBUG2
00166 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00167 "Error destroying m_ReadCond: %u (%s)", status,
00168 strerror( status ) );
00169 #endif
00170 }
00171
00172 status = pthread_cond_destroy( &m_ReadStarted );
00173 if( status < 0 )
00174 {
00175 #ifdef RIO_DEBUG2
00176 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00177 "Error destroying m_ReadStarted: %u (%s)", status,
00178 strerror( status ) );
00179 #endif
00180 }
00181
00182 status = pthread_cond_destroy( &m_ThreadBlocked );
00183 if( status < 0 )
00184 {
00185 #ifdef RIO_DEBUG2
00186 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00187 "Error destroying m_ThreadBlocked: %u (%s)", status,
00188 strerror( status ) );
00189 #endif
00190 }
00191
00192 status = pthread_mutex_destroy( &m_Mutex );
00193 if( status < 0 )
00194 {
00195 #ifdef RIO_DEBUG2
00196 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00197 "Error destroying m_Mutex: %u (%s)", status,
00198 strerror( status ) );
00199 #endif
00200 }
00201 }
00202
00203
00204
00205 bool CRioModule::SendBlock( const char *Data, unsigned int DataSize )
00206 {
00207 apr_bucket_brigade *bb;
00208 apr_bucket *b;
00209 apr_status_t rv;
00210 unsigned int NextFragment, TotalFragments, FragmentSize, SendDataSize;
00211 const char *PosNextFragment;
00212
00213
00214
00215 FragmentSize = m_FragmentSize;
00216 if( FragmentSize > DataSize )
00217 {
00218 #ifdef RIO_DEBUG2
00219 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00220 "Warning: fragment size %u > datasize %u. "
00221 "Setting to data size", FragmentSize, DataSize );
00222 #endif
00223 FragmentSize = DataSize;
00224 }
00225 #ifdef RIO_DEBUG2
00226 if( ( DataSize % FragmentSize ) != 0 )
00227 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00228 "Warning: data size %u is not multiple of fragment "
00229 "size %u. Last fragment will be smaller", DataSize,
00230 FragmentSize );
00231 #endif
00232
00233
00234 TotalFragments = ( DataSize + FragmentSize - 1 ) / FragmentSize;
00235 NextFragment = 0;
00236
00237 #ifdef RIO_DEBUG2
00238 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00239 "Trying to send %u bytes: %u fragments of max size %u",
00240 DataSize, TotalFragments, FragmentSize );
00241 #endif
00242
00243 while( NextFragment < TotalFragments )
00244 {
00245
00246 if( NextFragment < ( TotalFragments - 1 ) )
00247 SendDataSize = FragmentSize;
00248 else
00249 SendDataSize = DataSize - ( ( TotalFragments - 1 ) *
00250 FragmentSize );
00251
00252 #ifdef RIO_DEBUG2
00253 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00254 "Trying to send fragment %u/%u with %u bytes",
00255 NextFragment + 1, TotalFragments, SendDataSize );
00256 #endif
00257
00258
00259 bb = apr_brigade_create( m_Request->pool,
00260 m_Request->connection->bucket_alloc );
00261 if( bb == NULL )
00262 {
00263 #ifdef RIO_DEBUG2
00264 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00265 "unable to create brigade" );
00266 #endif
00267
00268 m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00269 return false;
00270 }
00271
00272 PosNextFragment = &Data[ NextFragment * FragmentSize ];
00273 rv = apr_brigade_write( bb, NULL, NULL, PosNextFragment,
00274 SendDataSize );
00275 if( rv != APR_SUCCESS )
00276 {
00277 #ifdef RIO_DEBUG2
00278 ap_log_rerror( APLOG_MARK, APLOG_ERR, rv, m_Request,
00279 "unable to write data in brigade" );
00280 #endif
00281
00282 m_ApacheStatus = rv;
00283 return false;
00284 }
00285
00286
00287 b = apr_bucket_flush_create( m_Request->connection->bucket_alloc );
00288 if( b == NULL )
00289 {
00290 #ifdef RIO_DEBUG2
00291 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00292 "unable to create flush bucket" );
00293 #endif
00294
00295 m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00296 return false;
00297 }
00298
00299
00300 APR_BRIGADE_INSERT_TAIL( bb, b );
00301
00302
00303 rv = ap_pass_brigade( m_Request->output_filters, bb );
00304 if( rv != APR_SUCCESS )
00305 {
00306 #ifdef RIO_DEBUG2
00307 ap_log_rerror( APLOG_MARK, APLOG_ERR, rv, m_Request,
00308 "unable to pass brigade to filters" );
00309 #endif
00310
00311 m_ApacheStatus = rv;
00312 return false;
00313 }
00314
00315 rv = ap_fflush( m_Request->output_filters, bb );
00316 if( rv != APR_SUCCESS )
00317 {
00318 #ifdef RIO_DEBUG2
00319 ap_log_rerror( APLOG_MARK, APLOG_ERR, rv, m_Request,
00320 "unable to execute fflush" );
00321 #endif
00322
00323 m_ApacheStatus = rv;
00324 return false;
00325 }
00326 rv = apr_brigade_destroy( bb );
00327 if( rv != APR_SUCCESS )
00328 {
00329 #ifdef RIO_DEBUG2
00330 ap_log_rerror( APLOG_MARK, APLOG_ERR, rv, m_Request,
00331 "unable to destroy brigade" );
00332 #endif
00333
00334 m_ApacheStatus = rv;
00335 return false;
00336 }
00337
00338 NextFragment++;
00339 }
00340
00341 return true;
00342 }
00343
00344
00345
00346 bool CRioModule::ReceiveBlock( char *Data, unsigned int DataSize )
00347 {
00348 return true;
00349 }
00350
00351
00352 bool CRioModule::TerminateCopyToClient()
00353 {
00354 apr_bucket_brigade *bb;
00355 apr_bucket *b;
00356 apr_status_t rv;
00357
00358
00359
00360 bb = apr_brigade_create( m_Request->pool,
00361 m_Request->connection->bucket_alloc );
00362 if( bb == NULL )
00363 {
00364 #ifdef RIO_DEBUG2
00365 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00366 "unable to create brigade" );
00367 #endif
00368
00369 m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00370 return false;
00371 }
00372
00373
00374 b = apr_bucket_eos_create( m_Request->connection->bucket_alloc );
00375 if( b == NULL )
00376 {
00377 #ifdef RIO_DEBUG2
00378 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00379 "unable to create EOS bucket" );
00380 #endif
00381
00382 m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00383 return false;
00384 }
00385
00386
00387 APR_BRIGADE_INSERT_TAIL( bb, b );
00388
00389
00390 rv = ap_pass_brigade( m_Request->output_filters, bb );
00391 if( rv != APR_SUCCESS )
00392 {
00393 #ifdef RIO_DEBUG2
00394 ap_log_rerror( APLOG_MARK, APLOG_ERR, rv, m_Request,
00395 "unable to pass brigade to filters" );
00396 #endif
00397
00398 m_ApacheStatus = rv;
00399 return false;
00400 }
00401
00402 rv = ap_fflush( m_Request->output_filters, bb );
00403 if( rv != APR_SUCCESS )
00404 {
00405 #ifdef RIO_DEBUG2
00406 ap_log_rerror( APLOG_MARK, APLOG_ERR, rv, m_Request,
00407 "unable to execute fflush" );
00408 #endif
00409
00410 m_ApacheStatus = rv;
00411 return false;
00412 }
00413 else
00414 return true;
00415 }
00416
00417
00418 bool CRioModule::OpenRioSession( char *ServerName, char *UserName,
00419 char *UserPassword )
00420 {
00421 RioResult hResult;
00422
00423
00424 if( m_isSessionOpen )
00425 {
00426 m_RioStatus = ERROR_RIOSESSION + ERROR_SESSION_ALREADY_OPENED;
00427
00428 #ifdef RIO_DEBUG2
00429 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00430 "Error opening RIO session (1): %u (%s)", m_RioStatus,
00431 GetErrorDescription( m_RioStatus ).c_str()
00432 );
00433 #endif
00434
00435 return false;
00436 }
00437
00438
00439 m_Session = new CRioSession;
00440 if( m_Session == NULL )
00441 {
00442 m_RioStatus = ERROR_RIOSESSION + ERROR_MEMORY;
00443
00444 #ifdef RIO_DEBUG2
00445 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00446 "Error creating RIO session: %u (%s)", m_RioStatus,
00447 GetErrorDescription( m_RioStatus ).c_str() );
00448 #endif
00449
00450 return false;
00451 }
00452
00453
00454
00455 hResult = m_Session->Connect( ServerName, UserName, UserPassword, 1 );
00456 if( FAILED( hResult ) )
00457 {
00458 m_RioStatus = hResult;
00459
00460 #ifdef RIO_DEBUG2
00461 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00462 "Error opening RIO session (2): %u (%s)", hResult,
00463 GetErrorDescription( hResult ).c_str() );
00464 #endif
00465
00466 return false;
00467 }
00468
00469 m_isSessionOpen = true;
00470
00471 return true;
00472 }
00473
00474
00475 bool CRioModule::CloseRioSession()
00476 {
00477 RioResult hResult;
00478
00479
00480 if( ( m_Session == NULL ) || ( !m_isSessionOpen ) )
00481 {
00482 if( m_Session == NULL )
00483 m_RioStatus = ERROR_RIOSESSION + ERROR_NOT_INITIALIZED;
00484 else
00485 m_RioStatus = ERROR_RIOSESSION + ERROR_SESSION_NOT_OPENED;
00486
00487 #ifdef RIO_DEBUG2
00488 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00489 "Error closing RIO session (1): %u (%s)", m_RioStatus,
00490 GetErrorDescription( m_RioStatus ).c_str() );
00491 #endif
00492
00493 return false;
00494 }
00495
00496
00497 hResult = m_Session->Disconnect();
00498 if( FAILED( hResult ) )
00499 {
00500 m_RioStatus = hResult;
00501
00502 #ifdef RIO_DEBUG2
00503 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00504 "Error closing RIO session (2): %u (%s)", m_RioStatus,
00505 GetErrorDescription( m_RioStatus ).c_str() );
00506 #endif
00507
00508 return false;
00509 }
00510
00511
00512 delete m_Session;
00513
00514 m_isSessionOpen = false;
00515
00516 return true;
00517 }
00518
00519
00520 bool CRioModule::OpenRioStream( bool UseRealTime, RioStreamDirection Direction )
00521 {
00522 RioStreamTraffic Traffic;
00523 RioResult hResult;
00524
00525
00526
00527 double Rate = 187.5e+03;
00528
00529
00530 static const int MaxRequests = 20;
00531
00532
00533 if( m_isStreamOpen )
00534 {
00535 m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_ALREADY_OPENED;
00536
00537 #ifdef RIO_DEBUG2
00538 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00539 "Error opening RIO stream (1): %u (%s)",
00540 m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
00541 );
00542 #endif
00543
00544 return false;
00545 }
00546
00547
00548 if( ( m_Session == NULL ) || ( !m_isSessionOpen ) )
00549 {
00550 if( m_Session == NULL )
00551 m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
00552 else
00553 m_RioStatus = ERROR_RIOSTREAM + ERROR_SESSION_NOT_OPENED;
00554
00555 #ifdef RIO_DEBUG2
00556 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00557 "Erro opening RIO stream (2): %u (%s)", m_RioStatus,
00558 GetErrorDescription( m_RioStatus ).c_str() );
00559 #endif
00560
00561 return false;
00562 }
00563
00564
00565 m_Stream = new CRioStream();
00566 if( m_Stream == NULL )
00567 {
00568 m_RioStatus = ERROR_RIOSTREAM + ERROR_MEMORY;
00569
00570 #ifdef RIO_DEBUG2
00571 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00572 "Error creating RIO stream: %u (%s)", m_RioStatus,
00573 GetErrorDescription( m_RioStatus ).c_str()
00574 );
00575 #endif
00576
00577 return false;
00578 }
00579
00580
00581 if( UseRealTime )
00582 {
00583 Traffic.Type = RIO_TRAFFIC_VBR;
00584 Traffic.MaxRequests = 1;
00585
00586
00587
00588 Rate = Rate * 1.5;
00589
00590
00591
00592 Traffic.TrafficVBR.Rate = Rate;
00593 }
00594 else
00595 {
00596 Traffic.Type = RIO_TRAFFIC_NRT;
00597 Traffic.TrafficNRT.Reserved = 0;
00598 Traffic.MaxRequests = MaxRequests;
00599 }
00600 Traffic.Direction = Direction;
00601 Traffic.LogicalBlockSize = m_BlockSize;
00602
00603
00604 hResult = m_Stream->Open( &Traffic, m_Session );
00605 if( FAILED( hResult ) )
00606 {
00607 m_RioStatus = hResult;
00608
00609 #ifdef RIO_DEBUG2
00610 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00611 "Error opening RIO stream (3): %u (%s)",
00612 m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
00613 );
00614 #endif
00615
00616 return false;
00617 }
00618
00619 m_isStreamOpen = true;
00620
00621 return true;
00622 }
00623
00624 bool CRioModule::CloseRioStream()
00625 {
00626 RioResult hResult;
00627 bool Status;
00628
00629
00630 if( ( m_Stream == NULL ) || ( !m_isStreamOpen ) )
00631 {
00632 if( m_Stream == NULL )
00633 m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
00634 else
00635 m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_NOT_OPENED;
00636
00637 #ifdef RIO_DEBUG2
00638 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00639 "Error closing RIO stream (1): %u (%s)",
00640 m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
00641 );
00642 #endif
00643
00644 return false;
00645 }
00646
00647
00648 hResult = m_Stream->Close();
00649 if( FAILED( hResult ) )
00650 {
00651 m_RioStatus = hResult;
00652
00653 #ifdef RIO_DEBUG2
00654 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00655 "Error closing RIO stream (2): %u (%s)",
00656 m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
00657 );
00658 #endif
00659
00660 Status = false;
00661 }
00662 else
00663 Status = true;
00664
00665 m_isStreamOpen = false;
00666
00667
00668 delete m_Stream;
00669
00670 return Status;
00671 }
00672
00673
00674 bool CRioModule::OpenRioObject( char *FileName, RioAccess Access )
00675 {
00676 RioResult hResult;
00677
00678
00679 if( m_isObjectOpen )
00680 {
00681 m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_ALREADY_OPENED;
00682
00683 #ifdef RIO_DEBUG2
00684 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00685 "Error opening object (1): %u (%s)", m_RioStatus,
00686 GetErrorDescription( m_RioStatus ).c_str() );
00687 #endif
00688
00689 return false;
00690 }
00691
00692
00693 if( ( m_Stream == NULL ) || ( !m_isStreamOpen ) )
00694 {
00695 if( m_Stream == NULL )
00696 m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
00697 else
00698 m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_NOT_OPENED;
00699
00700 #ifdef RIO_DEBUG2
00701 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00702 "Erro opening object (2): %u (%s)", m_RioStatus,
00703 GetErrorDescription( m_RioStatus ).c_str() );
00704 #endif
00705
00706 return false;
00707 }
00708
00709
00710 m_Object = new CRioObject;
00711 if( m_Object == NULL )
00712 {
00713 m_RioStatus = ERROR_RIOOBJECT + ERROR_MEMORY;
00714
00715 #ifdef RIO_DEBUG2
00716 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00717 "Error creating RIO object: %u (%s)", m_RioStatus,
00718 GetErrorDescription( m_RioStatus ).c_str()
00719 );
00720 #endif
00721
00722 return false;
00723 }
00724
00725
00726
00727 hResult = m_Object->Open( FileName, Access, m_Stream );
00728 if( FAILED( hResult ) )
00729 {
00730 m_RioStatus = hResult;
00731
00732 #ifdef RIO_DEBUG2
00733 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00734 "Erro opening object (4): %u (%s)", m_RioStatus,
00735 GetErrorDescription( m_RioStatus ).c_str() );
00736 #endif
00737
00738 return false;
00739 }
00740 else
00741 {
00742 m_isObjectOpen = true;
00743
00744 return true;
00745 }
00746 }
00747
00748
00749 bool CRioModule::CloseRioObject()
00750 {
00751 RioResult hResult;
00752
00753
00754 if( ( m_Object == NULL ) || ( !m_isObjectOpen ) )
00755 {
00756 if( m_Object == NULL )
00757 m_RioStatus = ERROR_RIOOBJECT + ERROR_NOT_INITIALIZED;
00758 else
00759 m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_NOT_OPENED;
00760
00761 #ifdef RIO_DEBUG2
00762 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00763 "Error closing object (1): %u (%s)", m_RioStatus,
00764 GetErrorDescription( m_RioStatus ).c_str() );
00765 #endif
00766
00767 return false;
00768 }
00769
00770
00771 hResult = m_Object->Close();
00772 if( FAILED( hResult ) )
00773 {
00774 m_RioStatus = hResult;
00775
00776 #ifdef RIO_DEBUG2
00777 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00778 "Error closing object (2): %u (%s)", m_RioStatus,
00779 GetErrorDescription( m_RioStatus ).c_str() );
00780 #endif
00781 }
00782
00783
00784 if( ( m_Stream == NULL ) || ( !m_isStreamOpen ) )
00785 {
00786 if( m_Stream == NULL )
00787 m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
00788 else
00789 m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_NOT_OPENED;
00790
00791 #ifdef RIO_DEBUG2
00792 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00793 "Error closing object (3): %u (%s)", m_RioStatus,
00794 GetErrorDescription( m_RioStatus ).c_str()
00795 );
00796 #endif
00797
00798 return false;
00799 }
00800
00801
00802 delete m_Object;
00803
00804 m_isObjectOpen = false;
00805
00806 return true;
00807 }
00808
00809
00810
00811 void ModuleReadCallBack( RioRequest *Request )
00812 {
00813 CRioModule *Module = ( CRioModule* ) Request->User;
00814
00815 #ifdef RIO_DEBUG2
00816 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->GetRequest(),
00817 "Block %u arrived. Sending signal!", Request->Block );
00818 #endif
00819
00820
00821 if( !Module->SendSignal() )
00822 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->GetRequest(),
00823 "Error when executing SendSignal" );
00824 }
00825
00826
00827 bool CRioModule::ReadRioObjectBlock( RioBlock Block )
00828 {
00829 RioResult hResult;
00830 RioRequest Request;
00831 int ServerAddr, ServerPort, SendAck = 0;
00832 int status;
00833
00834 bool CopyBlock;
00835
00836 #ifdef RIO_DEBUG2
00837 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00838 "Trying reading block %u", Block );
00839 #endif
00840
00841
00842 unsigned int numberofretrys = 0;
00843
00844
00845 if( ( m_Object == NULL ) || ( !m_isObjectOpen ) )
00846 {
00847 if( m_Object == NULL )
00848 m_RioStatus = ERROR_RIOOBJECT + ERROR_NOT_INITIALIZED;
00849 else
00850 m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_NOT_OPENED;
00851
00852 #ifdef RIO_DEBUG2
00853 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00854 "Object not opened: %u (%s)", m_RioStatus,
00855 GetErrorDescription( m_RioStatus ).c_str() );
00856 #endif
00857
00858 return false;
00859 }
00860
00861
00862 Request.Size = m_BlockSize;
00863 Request.Buffer = m_RioBuffer;
00864 Request.CallBackFunction = ModuleReadCallBack;
00865 Request.User = (void *) this;
00866 Request.Block = Block;
00867 Request.Result = S_OK;
00868 Request.Status = RIO_REQUEST_FREE;
00869
00870 if( m_Stream->GetTrafficType() == RIO_TRAFFIC_NRT )
00871 {
00872 CopyBlock = true;
00873 while( CopyBlock )
00874 {
00875
00876
00877
00878
00879 status = pthread_mutex_lock( &m_ReadMutex );
00880 if( status != 0 )
00881 {
00882 m_SystemStatus = status;
00883
00884 #ifdef RIO_DEBUG2
00885 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00886 "Error reading block %u (1.2): %u (%s)",
00887 Block, m_SystemStatus,
00888 strerror( m_SystemStatus ) );
00889 #endif
00890
00891 return false;
00892 }
00893
00894 hResult = m_Object->StreamRead( &Request );
00895
00896 if( FAILED( hResult ) )
00897 {
00898 m_RioStatus = hResult;
00899
00900 #ifdef RIO_DEBUG2
00901 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00902 "Error reading block %u (1.1): %u (%s)",
00903 Block, m_RioStatus,
00904 GetErrorDescription( m_RioStatus ).c_str() );
00905 #endif
00906
00907 return false;
00908 }
00909
00910 status = pthread_cond_wait( &m_ReadCond, &m_ReadMutex );
00911 if( status != 0 )
00912 {
00913 m_SystemStatus = status;
00914
00915 #ifdef RIO_DEBUG2
00916 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00917 "Error reading block %u (1.3): %u (%s)",
00918 Block, m_SystemStatus,
00919 strerror( m_SystemStatus ) );
00920 #endif
00921 status = pthread_mutex_unlock( &m_ReadMutex );
00922 if( status != 0 )
00923 {
00924 m_SystemStatus = status;
00925
00926 #ifdef RIO_DEBUG2
00927 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00928 "Error unlocking mutex: %u (%s)", status,
00929 strerror( status ) );
00930 #endif
00931 }
00932
00933 return false;
00934 }
00935
00936 status = pthread_mutex_unlock( &m_ReadMutex );
00937 if( status != 0 )
00938 {
00939 m_SystemStatus = status;
00940
00941 #ifdef RIO_DEBUG2
00942 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00943 "Error reading block %u (1.4): %u (%s)",
00944 Block, m_SystemStatus,
00945 strerror( m_SystemStatus ) );
00946 #endif
00947
00948 return false;
00949 }
00950
00951
00952
00953 if( Request.Result == S_OK )
00954 {
00955 CopyBlock = false;
00956 }
00957 else if( ( Request.Result & 0xFF ) ==
00958 ERROR_SERVICE_TEMPORARY_UNAVAILABLE )
00959 {
00960
00961
00962
00963
00964
00965
00966 numberofretrys++;
00967
00968 if( numberofretrys >= MAXNUMBEROFBLOCKRETRYS )
00969 {
00970 m_RioStatus = ERROR_RIOOBJECT +
00971 ERROR_SERVICE_TEMPORARY_UNAVAILABLE;
00972
00973 #ifdef RIO_DEBUG2
00974 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00975 "Error reading block %u (1.5): %u (%s)",
00976 Block, m_RioStatus,
00977 GetErrorDescription( m_RioStatus ).c_str() );
00978 #endif
00979
00980 return false;
00981 }
00982 }
00983 else
00984 {
00985 m_RioStatus = Request.Result;
00986
00987 #ifdef RIO_DEBUG2
00988 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
00989 "Error reading block %u (1.6): %u (%s)",
00990 Block, m_RioStatus,
00991 GetErrorDescription( m_RioStatus ).c_str() );
00992 #endif
00993
00994 return false;
00995 }
00996 }
00997 }
00998 else
00999 {
01000 struct timespec wt;
01001 struct timeval tv;
01002 bool PartialBlock = false;
01003
01004
01005 Request.reqid = -1;
01006 m_Object->Getmyaddr( &ServerAddr, &ServerPort );
01007
01008 status = pthread_mutex_lock( &m_ReadMutex );
01009 if( status != 0 )
01010 {
01011 m_SystemStatus = status;
01012
01013 #ifdef RIO_DEBUG2
01014 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01015 "Error reading block %u (2.2): %u (%s)",
01016 Block, m_SystemStatus, strerror( m_SystemStatus ) );
01017 #endif
01018
01019 return false;
01020 }
01021
01022 hResult = m_Object->StreamRead( &Request, SendAck, UNICASTTRAFFIC,
01023 ServerAddr, ntohs( ServerPort ) );
01024
01025 if( FAILED( hResult ) )
01026 {
01027 m_RioStatus = hResult;
01028
01029 #ifdef RIO_DEBUG2
01030 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01031 "Error reading block %u (2.1): %u (%s)",
01032 Block, m_RioStatus,
01033 GetErrorDescription( m_RioStatus ).c_str() );
01034 #endif
01035
01036 return false;
01037 }
01038
01039
01040
01041 gettimeofday( &tv, NULL );
01042 wt.tv_sec = tv.tv_sec + ( m_WaitTime / 1000 );
01043 wt.tv_nsec = ( tv.tv_usec * 1000 ) + ( ( m_WaitTime % 1000 ) *
01044 1000000 );
01045
01046 #ifdef RIO_DEBUG2
01047 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01048 "Esperando pelo bloco %u: tempo atual = %lu s, "
01049 "%lu micros; esperando ate o tempo %lu s e %lu nanos",
01050 Block, tv.tv_sec, tv.tv_usec, wt.tv_sec, wt.tv_nsec);
01051 #endif
01052
01053 if( wt.tv_nsec > 999999999 )
01054 {
01055 wt.tv_nsec = wt.tv_nsec - 999999999;
01056 wt.tv_sec++;
01057 }
01058
01059
01060
01061 status = pthread_cond_timedwait( &m_ReadCond, &m_ReadMutex, &wt );
01062 if( status == ETIMEDOUT )
01063 PartialBlock = true;
01064 else if( status != 0 )
01065 {
01066 m_SystemStatus = status;
01067
01068 #ifdef RIO_DEBUG2
01069 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01070 "Error reading block %u (2.3): %u (%s)",
01071 Block, m_SystemStatus, strerror( m_SystemStatus ) );
01072 #endif
01073
01074 status = pthread_mutex_unlock( &m_ReadMutex );
01075 if( status != 0 )
01076 {
01077 m_SystemStatus = status;
01078
01079 #ifdef RIO_DEBUG2
01080 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01081 "Error unlocking mutex: %u (%s)", status,
01082 strerror( status ) );
01083 #endif
01084 }
01085 return false;
01086 }
01087
01088 if( PartialBlock )
01089 {
01090
01091 #ifdef RIO_DEBUG2
01092 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01093 "Bloco %u recebido parcialmente devido a timeout.",
01094 Block );
01095 #endif
01096
01097 hResult = m_Object->FreeBlock( Request.reqid, UNICASTTRAFFIC );
01098 if( FAILED( hResult ) )
01099 {
01100 m_RioStatus = hResult;
01101
01102 #ifdef RIO_DEBUG2
01103 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01104 "Error cancelling block %u: %u (%s)",
01105 Block, m_RioStatus,
01106 GetErrorDescription( m_RioStatus ).c_str() );
01107 #endif
01108
01109 status = pthread_mutex_unlock( &m_ReadMutex );
01110 if( status != 0 )
01111 {
01112 m_SystemStatus = status;
01113
01114 #ifdef RIO_DEBUG2
01115 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01116 "Error unlocking mutex: %u (%s)", status,
01117 strerror( status ) );
01118 #endif
01119 }
01120
01121 return false;
01122 }
01123
01124
01125
01126
01127
01128
01129
01130 if( hResult > 0 )
01131 {
01132
01133 status = pthread_cond_wait( &m_ReadCond, &m_ReadMutex );
01134 if( status != 0 )
01135 {
01136 m_SystemStatus = status;
01137
01138 #ifdef RIO_DEBUG2
01139 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01140 "Error reading block %u (2.4): %u (%s)",
01141 Block, m_SystemStatus,
01142 strerror( m_SystemStatus ) );
01143 #endif
01144
01145 status = pthread_mutex_unlock( &m_ReadMutex );
01146 if( status != 0 )
01147 {
01148 m_SystemStatus = status;
01149
01150 #ifdef RIO_DEBUG2
01151 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01152 "Error unlocking mutex: %u (%s)", status,
01153 strerror( status ) );
01154 #endif
01155 }
01156
01157 return false;
01158 }
01159
01160
01161 if( Request.Result != S_OK )
01162 {
01163 m_RioStatus = Request.Result;
01164
01165 #ifdef RIO_DEBUG2
01166 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01167 "Error reading block %u (1.6): %u (%s)",
01168 Block, m_RioStatus,
01169 GetErrorDescription( m_RioStatus ).c_str()
01170 );
01171 #endif
01172
01173 status = pthread_mutex_unlock( &m_ReadMutex );
01174 if( status != 0 )
01175 {
01176 m_SystemStatus = status;
01177
01178 #ifdef RIO_DEBUG2
01179 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01180 "Error unlocking mutex: %u (%s)", status,
01181 strerror( status ) );
01182 #endif
01183 }
01184
01185 return false;
01186 }
01187 }
01188
01189 #ifdef RIO_DEBUG2
01190 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01191 "Bloco %u recebido parcialmente com %u bytes.",
01192 Block, hResult );
01193 #endif
01194
01195
01196 }
01197
01198 status = pthread_mutex_unlock( &m_ReadMutex );
01199 if( status != 0 )
01200 {
01201 m_SystemStatus = status;
01202
01203 #ifdef RIO_DEBUG2
01204 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01205 "Error reading block %u (2.4): %u (%s)",
01206 Block, m_SystemStatus, strerror( m_SystemStatus ) );
01207 #endif
01208
01209 return false;
01210 }
01211 }
01212
01213 return true;
01214 }
01215
01216
01217
01218 bool CRioModule::WriteRioObjectBlock( RioBlock Block )
01219 {
01220 return true;
01221 }
01222
01223
01224 void *CRioModule::ReadThreadFunction( void *Class )
01225 {
01226 CRioModule *Module;
01227 RioBlock Block;
01228 bool NoError;
01229 int status;
01230
01231 Module = ( CRioModule * ) Class;
01232
01233 #ifdef RIO_DEBUG2
01234 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01235 "READTHREADID %lu", syscall( SYS_gettid ) );
01236 #endif
01237
01238
01239
01240 while( 1 )
01241 {
01242
01243 if( Module->m_ThreadCanceled )
01244 return NULL;
01245
01246
01247 status = pthread_mutex_lock( &Module->m_Mutex );
01248 if( status < 0 )
01249 {
01250 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01251 "error locking mutex m_Mutex" );
01252 }
01253
01254
01255 status = pthread_cond_signal( &Module->m_ThreadBlocked );
01256 if( status < 0 )
01257 {
01258 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01259 "error signalling condition variable m_ThreadBlocked" );
01260 }
01261
01262
01263
01264 if( !Module->m_isReadingFile )
01265 {
01266 status = pthread_cond_wait( &Module->m_ReadStarted,
01267 &Module->m_Mutex );
01268
01269 if( status < 0 )
01270 {
01271 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01272 "error waiting in condition variable m_ReadStarted" );
01273 }
01274
01275 }
01276
01277 while( ( Module->m_isReadingFile ) && ( !Module->m_ThreadCanceled ) )
01278 {
01279
01280 Block = Module->m_RioBlock;
01281
01282
01283
01284 status = pthread_mutex_unlock( &Module->m_Mutex );
01285 if( status < 0 )
01286 {
01287 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01288 "error unlocking mutex m_Mutex" );
01289 }
01290
01291
01292 NoError = Module->ReadRioObjectBlock( Block );
01293
01294
01295
01296 if( !NoError )
01297 {
01298 #ifdef RIO_DEBUG2
01299 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01300 "error executing ReadRioObjectBlock" );
01301 #endif
01302 }
01303 else
01304 {
01305 #ifdef RIO_DEBUG2
01306 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01307 "Trying to insert block %u in CircularBuffer!", Block );
01308 #endif
01309
01310
01311 NoError = Module->m_CircularBuffer->SetElement(
01312 Module->m_RioBuffer );
01313 if( !NoError )
01314 {
01315 Module->m_SystemStatus = Module->m_CircularBuffer->
01316 GetError();
01317
01318 #ifdef RIO_DEBUG2
01319 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0,
01320 Module->m_Request,
01321 "Error copying block %u to circular buffer: %u (%s)",
01322 Block, Module->m_SystemStatus,
01323 strerror( Module->m_SystemStatus ) );
01324 #endif
01325
01326 }
01327 }
01328
01329
01330
01331 status = pthread_mutex_lock( &Module->m_Mutex );
01332 if( status < 0 )
01333 {
01334 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01335 "error locking mutex m_Mutex" );
01336 }
01337
01338
01339
01340 Module->m_RioBlock++;
01341
01342
01343 if( ( Module->m_RioBlock >= Module->m_TotalBlocks ) ||
01344 ( !NoError ) )
01345 {
01346
01347
01348 Module->m_isReadingFile = false;
01349
01350
01351
01352 if( !NoError )
01353 Module->m_CircularBuffer->CancelGetElement();
01354
01355 }
01356 }
01357
01358 status = pthread_mutex_unlock( &Module->m_Mutex );
01359 if( status < 0 )
01360 {
01361 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Module->m_Request,
01362 "error unlocking mutex m_Mutex" );
01363 }
01364 }
01365 }
01366
01367
01368 bool CRioModule::CancelCopy()
01369 {
01370 int status;
01371 bool isReadingFile;
01372
01373
01374 status = pthread_mutex_lock( &m_Mutex );
01375 if( status < 0 )
01376 {
01377 m_SystemStatus = status;
01378
01379 #ifdef RIO_DEBUG2
01380 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01381 "Error locking m_Mutex: %u (%s)",
01382 m_SystemStatus, strerror( m_SystemStatus ) );
01383 #endif
01384
01385 return false;
01386 }
01387
01388
01389
01390 isReadingFile = m_isReadingFile;
01391
01392
01393
01394 m_isReadingFile = false;
01395 m_RioBlock = 0;
01396 m_SendBlock = 0;
01397 m_TotalBlocks = 0;
01398 m_isFirstBlock = false;
01399 m_StartFirstBlock = false;
01400 m_FileSize = 0;
01401
01402
01403 if( isReadingFile )
01404 {
01405
01406
01407 if( !m_CircularBuffer->CleanBuffer() )
01408 {
01409 #ifdef RIO_DEBUG2
01410 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01411 "Error when cleaning m_CircularBuffer" );
01412 #endif
01413 }
01414
01415
01416
01417 if( !TerminateCopyToClient() )
01418 {
01419 #ifdef RIO_DEBUG2
01420 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01421 "Error when executing TerminateCopyToClient" );
01422 #endif
01423 }
01424
01425 status = pthread_cond_wait( &m_ThreadBlocked, &m_Mutex );
01426
01427 if( status < 0 )
01428 {
01429 m_SystemStatus = status;
01430
01431 #ifdef RIO_DEBUG2
01432 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01433 "Error closing file: %u (%s)", m_SystemStatus,
01434 strerror( m_SystemStatus ) );
01435 #endif
01436
01437
01438 status = pthread_mutex_unlock( &m_Mutex );
01439 if( status < 0 )
01440 {
01441 m_SystemStatus = status;
01442
01443 #ifdef RIO_DEBUG2
01444 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01445 "Error unlocking m_Mutex: %u (%s)",
01446 m_SystemStatus, strerror( m_SystemStatus ) );
01447 #endif
01448
01449 }
01450
01451 return false;
01452 }
01453 }
01454
01455
01456 status = pthread_mutex_unlock( &m_Mutex );
01457 if( status < 0 )
01458 {
01459 m_SystemStatus = status;
01460
01461 #ifdef RIO_DEBUG2
01462 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01463 "Error unlocking m_Mutex: %u (%s)",
01464 m_SystemStatus, strerror( m_SystemStatus ) );
01465 #endif
01466
01467 return false;
01468 }
01469
01470 return true;
01471 }
01472
01473
01474
01475 bool CRioModule::SendFileHeader( const char *FileName )
01476 {
01477 const char *StartFinalExtension;
01478 const char *Header;
01479 unsigned int HeaderSize;
01480
01481
01482 StartFinalExtension = strrchr( FileName, '.' );
01483
01484
01485
01486 if( StartFinalExtension != NULL )
01487 {
01488
01489
01490 if( strcmp( StartFinalExtension + 1, "flv" ) == 0 )
01491 {
01492 Header = FLVX_HEADER;
01493 HeaderSize = FLVX_HEADER_LEN;
01494 }
01495 else
01496 {
01497
01498
01499 Header = NULL;
01500 HeaderSize = 0;
01501 }
01502
01503 if( Header != NULL )
01504 return SendBlock( Header, HeaderSize );
01505
01506 }
01507
01508 return true;
01509 }
01510
01511
01512 bool CRioModule::Start( char *ServerName, char *UserName, char *UserPassword,
01513 unsigned int BufferSize, unsigned int FragmentSize,
01514 unsigned int *BlockSize )
01515 {
01516 RioResult hResult;
01517 int error;
01518 int status;
01519
01520
01521 *BlockSize = 0;
01522
01523
01524 if( m_Started )
01525 {
01526 m_RioStatus = ERROR_RIOMODULE + ERROR_STARTED;
01527
01528 #ifdef RIO_DEBUG2
01529 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01530 "The module is already started" );
01531 #endif
01532
01533 return false;
01534
01535 }
01536
01537
01538 m_FragmentSize = FragmentSize;
01539
01540
01541 m_ServerName = new char[ strlen( ServerName ) + 1 ];
01542 if( m_ServerName == NULL )
01543 {
01544 m_SystemStatus = ENOMEM;
01545
01546 #ifdef RIO_DEBUG2
01547 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01548 "Insufficient memory to create m_ServerName" );
01549 #endif
01550
01551 return false;
01552 }
01553 strcpy( m_ServerName, ServerName );
01554
01555
01556
01557
01558
01559 if( !OpenRioSession( m_ServerName, UserName, UserPassword ) )
01560 {
01561 #ifdef RIO_DEBUG2
01562 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01563 "Error creating RioSession: %u (%s)",
01564 m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
01565 );
01566 #endif
01567 return false;
01568 }
01569
01570
01571 hResult = m_Session->GetBlockSize( &m_BlockSize );
01572 if( FAILED( hResult ) )
01573 {
01574 m_RioStatus = hResult;
01575
01576 #ifdef RIO_DEBUG2
01577 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01578 "Error getting block size: %u (%s)", m_RioStatus,
01579 GetErrorDescription( m_RioStatus ).c_str() );
01580 #endif
01581
01582 return false;
01583 }
01584
01585
01586
01587 m_RioBuffer = new char[ m_BlockSize ];
01588 if( m_RioBuffer == NULL )
01589 {
01590 m_SystemStatus = ENOMEM;
01591
01592 #ifdef RIO_DEBUG2
01593 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01594 "Erro allocating m_RioBuffer: %u (%s)",
01595 m_SystemStatus, strerror( m_SystemStatus ) );
01596 #endif
01597
01598 if( !CloseRioSession() )
01599 {
01600 #ifdef RIO_DEBUG2
01601 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01602 "Error closing RioSession: %u (%s)", m_RioStatus,
01603 GetErrorDescription( m_RioStatus ).c_str() );
01604 #endif
01605 }
01606
01607 return false;
01608 }
01609
01610
01611
01612 m_ApacheBuffer = new char[ m_BlockSize ];
01613 if( m_ApacheBuffer == NULL )
01614 {
01615 m_SystemStatus = ENOMEM;
01616
01617 #ifdef RIO_DEBUG2
01618 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01619 "Erro allocating block buffer: %u (%s)",
01620 m_SystemStatus, strerror( m_SystemStatus ) );
01621 #endif
01622
01623
01624 delete[] m_RioBuffer;
01625 m_RioBuffer = NULL;
01626
01627 if( !CloseRioSession() )
01628 {
01629 #ifdef RIO_DEBUG2
01630 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01631 "Error closing RioSession: %u (%s)", m_RioStatus,
01632 GetErrorDescription( m_RioStatus ).c_str() );
01633 #endif
01634 }
01635
01636 return false;
01637 }
01638
01639
01640
01641
01642 m_CircularBuffer = new CircularBuffer( m_Request->server, BufferSize,
01643 m_BlockSize );
01644 if( m_CircularBuffer == NULL )
01645 {
01646 m_SystemStatus = ENOMEM;
01647
01648 #ifdef RIO_DEBUG2
01649 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01650 "Erro allocating circular buffer: %u (%s)",
01651 m_SystemStatus, strerror( m_SystemStatus ) );
01652 #endif
01653
01654 if( !CloseRioSession() )
01655 {
01656 #ifdef RIO_DEBUG2
01657 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01658 "Error closing RioSession: %u (%s)", m_RioStatus,
01659 GetErrorDescription( m_RioStatus ).c_str() );
01660 #endif
01661 }
01662
01663
01664 delete[] m_RioBuffer;
01665 m_RioBuffer = NULL;
01666 delete[] m_ApacheBuffer;
01667 m_ApacheBuffer = NULL;
01668
01669
01670 delete m_CircularBuffer;
01671 m_CircularBuffer = NULL;
01672
01673 return false;
01674 }
01675
01676
01677 error = m_CircularBuffer->GetError();
01678 if( error != 0 )
01679 {
01680 m_SystemStatus = error;
01681
01682 #ifdef RIO_DEBUG2
01683 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01684 "Erro allocating circular buffer: %u (%s)",
01685 m_SystemStatus, strerror( m_SystemStatus ) );
01686 #endif
01687
01688 if( !CloseRioSession() )
01689 {
01690 #ifdef RIO_DEBUG2
01691 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01692 "Error closing RioSession: %u (%s)", m_RioStatus,
01693 GetErrorDescription( m_RioStatus ).c_str() );
01694 #endif
01695 }
01696
01697
01698
01699 return false;
01700 }
01701
01702
01703 m_ThreadCanceled = false;
01704
01705
01706
01707 status = pthread_create( &m_ReadThread, NULL, ReadThreadFunction,
01708 ( void * ) this );
01709 if( status < 0 )
01710 {
01711 m_SystemStatus = status;
01712
01713 #ifdef RIO_DEBUG2
01714 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01715 "Error creating copy thread: %u (%s)", m_SystemStatus,
01716 strerror( m_SystemStatus ) );
01717 #endif
01718
01719 if( !CloseRioSession() )
01720 {
01721 #ifdef RIO_DEBUG2
01722 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01723 "Error closing RioSession: %u (%s)", m_RioStatus,
01724 GetErrorDescription( m_RioStatus ).c_str() );
01725 #endif
01726 }
01727
01728
01729 delete[] m_RioBuffer;
01730 m_RioBuffer = NULL;
01731 delete[] m_ApacheBuffer;
01732 m_ApacheBuffer = NULL;
01733
01734
01735 delete m_CircularBuffer;
01736 m_CircularBuffer = NULL;
01737
01738 return false;
01739
01740 }
01741
01742
01743
01744 m_Started = true;
01745
01746
01747 *BlockSize = m_BlockSize;
01748
01749 return true;
01750 }
01751
01752
01753 bool CRioModule::Stop()
01754 {
01755 int status;
01756
01757
01758 if( !m_Started )
01759 {
01760 m_RioStatus = ERROR_RIOMODULE + ERROR_NOT_STARTED;
01761
01762 #ifdef RIO_DEBUG2
01763 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01764 "The object has not started" );
01765 #endif
01766
01767 return false;
01768
01769 }
01770
01771
01772 if( m_ReadThread != 0 )
01773 {
01774
01775
01776 m_ThreadCanceled = true;
01777
01778
01779 status = pthread_cond_signal( &m_ReadStarted );
01780 if( status < 0 )
01781 {
01782 m_SystemStatus = status;
01783
01784 #ifdef RIO_DEBUG2
01785 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01786 "Error signalling m_ReadStarted: %u (%s)",
01787 m_SystemStatus, strerror( m_SystemStatus ) );
01788 #endif
01789
01790 return false;
01791 }
01792
01793
01794 status = pthread_join( m_ReadThread, NULL );
01795
01796 if( status < 0 )
01797 {
01798 m_SystemStatus = status;
01799
01800 #ifdef RIO_DEBUG2
01801 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01802 "Error when joining ReadThread: %u (%s)", m_SystemStatus,
01803 strerror( m_SystemStatus ) );
01804 #endif
01805
01806 return false;
01807 }
01808 }
01809
01810
01811 if( m_isObjectOpen )
01812 Close();
01813
01814 if( m_isSessionOpen )
01815 CloseRioSession();
01816
01817
01818 if( m_ServerName != NULL )
01819 delete m_ServerName;
01820
01821
01822 delete[] m_RioBuffer;
01823 m_RioBuffer = NULL;
01824 delete[] m_ApacheBuffer;
01825 m_ApacheBuffer = NULL;
01826
01827
01828 delete m_CircularBuffer;
01829 m_CircularBuffer = NULL;
01830
01831
01832 m_Started = false;
01833
01834 return true;
01835 }
01836
01837
01838 bool CRioModule::Open( const char *FileName, RioAccess Access, bool UseRealTime,
01839 unsigned int WaitTime, RioObjectSize StartPosition,
01840 RioObjectSize EndPosition, bool SendHeader,
01841 RioObjectSize *FileSize, unsigned int *TotalBlocks )
01842 {
01843 RioResult hResult;
01844 int status;
01845 RioStreamDirection Direction;
01846
01847
01848 *FileSize = 0;
01849 *TotalBlocks = 0;
01850
01851
01852 status = pthread_mutex_lock( &m_Mutex );
01853 if( status < 0 )
01854 {
01855 m_SystemStatus = status;
01856
01857 #ifdef RIO_DEBUG2
01858 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01859 "Error locking m_Mutex: %u (%s)",
01860 m_SystemStatus, strerror( m_SystemStatus ) );
01861 #endif
01862
01863 return false;
01864 }
01865
01866
01867 if( ( m_isReadingFile ) || ( m_SendBlock < m_TotalBlocks ) )
01868 {
01869 #ifdef RIO_DEBUG2
01870 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01871 "A copy is already in progress" );
01872 #endif
01873
01874
01875 status = pthread_mutex_unlock( &m_Mutex );
01876 if( status < 0 )
01877 {
01878 m_SystemStatus = status;
01879
01880 #ifdef RIO_DEBUG2
01881 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01882 "Error unlocking m_Mutex: %u (%s)",
01883 m_SystemStatus, strerror( m_SystemStatus ) );
01884 #endif
01885 }
01886
01887 return false;
01888 }
01889
01890
01891 status = pthread_mutex_unlock( &m_Mutex );
01892 if( status < 0 )
01893 {
01894 m_SystemStatus = status;
01895
01896 #ifdef RIO_DEBUG2
01897 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01898 "Error unlocking m_Mutex: %u (%s)",
01899 m_SystemStatus, strerror( m_SystemStatus ) );
01900 #endif
01901
01902 return false;
01903 }
01904
01905
01906
01907 m_UseRealTime = UseRealTime;
01908
01909
01910 m_Access = Access;
01911
01912
01913 if( ( ( m_Access & RIO_READ_MASK ) != 0 ) &&
01914 ( ( m_Access & RIO_WRITE_MASK ) != 0 ) )
01915 {
01916 m_RioStatus = ERROR_RIOMODULE + ERROR_INVALID_ACCESS_TYPE;
01917
01918 #ifdef RIO_DEBUG2
01919 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01920 "Cannot simultaniously read/write files: %u (%s)",
01921 m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
01922 );
01923 #endif
01924
01925 return false;
01926
01927 }
01928
01929
01930 if( ( m_Access & RIO_READ_MASK ) != 0 )
01931 Direction = RioStreamDirectionRead;
01932 else
01933 Direction = RioStreamDirectionWrite;
01934
01935
01936
01937 if( m_FileName != NULL )
01938 delete m_FileName;
01939
01940 m_FileName = new char[ strlen( FileName ) + 1 ];
01941 if( m_FileName == NULL )
01942 {
01943 m_SystemStatus = ENOMEM;
01944
01945 #ifdef RIO_DEBUG2
01946 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01947 "Error when creating filename: %u (%s)", m_SystemStatus,
01948 strerror( m_SystemStatus ) );
01949 #endif
01950
01951 return false;
01952 }
01953
01954 strcpy( m_FileName, FileName );
01955
01956
01957 if( !OpenRioStream( m_UseRealTime, Direction ) )
01958 {
01959 #ifdef RIO_DEBUG2
01960 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01961 "Error creating RIO Stream: %u (%s)", m_RioStatus,
01962 GetErrorDescription( m_RioStatus ).c_str() );
01963 #endif
01964
01965 return false;
01966 }
01967
01968
01969 if( !OpenRioObject( m_FileName, m_Access ) )
01970 {
01971 #ifdef RIO_DEBUG2
01972 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01973 "Error opening RioObject: %u (%s)", m_RioStatus,
01974 GetErrorDescription( m_RioStatus ).c_str() );
01975 #endif
01976
01977 if( !CloseRioStream() )
01978 {
01979 #ifdef RIO_DEBUG2
01980 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
01981 "Error closing RioStream: %u (%s)", m_RioStatus,
01982 GetErrorDescription( m_RioStatus ).c_str() );
01983 #endif
01984 }
01985
01986 return false;
01987 }
01988
01989
01990
01991 if( ( m_Access & RIO_READ_MASK ) != 0 )
01992 {
01993
01994 hResult = m_Object->GetSize( &m_FileSize );
01995
01996 if( FAILED( hResult ) )
01997 {
01998 m_RioStatus = hResult;
01999
02000 #ifdef RIO_DEBUG2
02001 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02002 "Error getting object size: %u (%s)", m_RioStatus,
02003 GetErrorDescription( m_RioStatus ).c_str() );
02004 #endif
02005
02006 return false;
02007 }
02008
02009
02010
02011 if( ( ( StartPosition < -m_FileSize ) ) ||
02012 ( StartPosition >= m_FileSize ) )
02013 {
02014 m_RioStatus = ERROR_RIOMODULE + ERROR_INVALID_PARAM;
02015
02016 #ifdef RIO_DEBUG2
02017 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02018 "Invalid start position %lld >= file size %lld: "
02019 "%u (%s)", StartPosition, m_FileSize, m_RioStatus,
02020 GetErrorDescription( m_RioStatus ).c_str() );
02021 #endif
02022
02023 return false;
02024 }
02025
02026
02027
02028
02029
02030 if( StartPosition < 0 )
02031 StartPosition = m_FileSize + StartPosition;
02032
02033
02034
02035 if( ( EndPosition != -1 ) && ( EndPosition >= m_FileSize ) )
02036 {
02037 m_RioStatus = ERROR_RIOMODULE + ERROR_INVALID_PARAM;
02038
02039 #ifdef RIO_DEBUG2
02040 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02041 "Invalid end position %lld >= file size %lld: "
02042 "%u (%s)", EndPosition, m_FileSize, m_RioStatus,
02043 GetErrorDescription( m_RioStatus ).c_str() );
02044 #endif
02045
02046 return false;
02047 }
02048
02049 if( ( EndPosition != -1 ) && ( EndPosition < StartPosition ) )
02050 {
02051 m_RioStatus = ERROR_RIOMODULE + ERROR_INVALID_PARAM;
02052
02053 #ifdef RIO_DEBUG2
02054 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02055 "Invalid end position %lld >= start position %lld: "
02056 "%u (%s)", EndPosition, StartPosition, m_RioStatus,
02057 GetErrorDescription( m_RioStatus ).c_str() );
02058 #endif
02059
02060 return false;
02061 }
02062
02063
02064
02065 if( EndPosition == -1 )
02066 {
02067
02068 EndPosition = m_FileSize - 1;
02069 }
02070
02071
02072 status = pthread_mutex_lock( &m_Mutex );
02073 if( status < 0 )
02074 {
02075 m_SystemStatus = status;
02076
02077 #ifdef RIO_DEBUG2
02078 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02079 "Error locking m_Mutex: %u (%s)",
02080 m_SystemStatus, strerror( m_SystemStatus ) );
02081 #endif
02082
02083 return false;
02084 }
02085
02086
02087
02088
02089 if( WaitTime != 0 )
02090 m_WaitTime = WaitTime;
02091 else
02092 {
02093
02094 unsigned long long int Numerator, Denominator;
02095
02096 unsigned int VideoRate;
02097
02098
02099 hResult = m_Object->GetVideoRate( &VideoRate );
02100
02101 if( FAILED( hResult ) )
02102 {
02103 m_RioStatus = hResult;
02104
02105 #ifdef RIO_DEBUG2
02106 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02107 "Error getting video rate: %u (%s)", m_RioStatus,
02108 GetErrorDescription( m_RioStatus ).c_str() );
02109 #endif
02110
02111 return false;
02112 }
02113
02114 if( VideoRate > 0 )
02115 {
02116
02117
02118 Numerator = 125ull * ( ( unsigned long long ) m_BlockSize );
02119 Denominator = 8ull * ( ( unsigned long long ) VideoRate );
02120 m_WaitTime = (int) ( Numerator / Denominator );
02121 if( Numerator % Denominator != 0 )
02122 m_WaitTime++;
02123
02124 #ifdef RIO_DEBUG2
02125 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02126 "Computando o tempo do arquivo %s a partir da taxa "
02127 "de transmissao %u do objeto: %u", m_FileName,
02128 VideoRate, m_WaitTime );
02129 #endif
02130 }
02131 else
02132 {
02133 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02134 "Invalid video rate %d for object %s. Using default "
02135 "value %d", VideoRate, m_FileName, DEFAULT_WAITTIME
02136 );
02137 m_WaitTime = DEFAULT_WAITTIME;
02138 }
02139
02140 }
02141
02142 m_TotalBlocks = ( EndPosition + m_BlockSize ) / m_BlockSize;
02143
02144
02145 m_RioBlock = StartPosition / m_BlockSize;
02146 m_SendBlock = m_RioBlock;
02147
02148
02149 m_StartFirstBlock = StartPosition % m_BlockSize;
02150
02151
02152 m_EndPosition = EndPosition;
02153
02154
02155
02156 m_isFirstBlock = true;
02157
02158
02159 m_isReadingFile = true;
02160
02161
02162 *FileSize = m_FileSize;
02163 *TotalBlocks = m_TotalBlocks;
02164
02165
02166 status = pthread_mutex_unlock( &m_Mutex );
02167 if( status < 0 )
02168 {
02169 m_SystemStatus = status;
02170
02171 #ifdef RIO_DEBUG2
02172 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02173 "Error unlocking m_Mutex: %u (%s)",
02174 m_SystemStatus, strerror( m_SystemStatus ) );
02175 #endif
02176
02177 return false;
02178 }
02179
02180
02181
02182 status = pthread_cond_signal( &m_ReadStarted );
02183 if( status < 0 )
02184 {
02185 m_SystemStatus = status;
02186
02187 #ifdef RIO_DEBUG2
02188 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02189 "Error signalling m_ReadStarted: %u (%s)",
02190 m_SystemStatus, strerror( m_SystemStatus ) );
02191 #endif
02192
02193 return false;
02194 }
02195
02196
02197 ap_set_content_length( m_Request, EndPosition - StartPosition + 1 );
02198
02199
02200
02201
02202
02203 if( ( StartPosition > 0 ) && ( SendHeader ) )
02204 {
02205 if( !SendFileHeader( FileName ) )
02206 {
02207 #ifdef RIO_DEBUG2
02208 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02209 "Error when sending header for file %s ",
02210 FileName );
02211 #endif
02212
02213 return false;
02214 }
02215 }
02216
02217 }
02218
02219 return true;
02220 }
02221
02222
02223 bool CRioModule::Close()
02224 {
02225
02226 if( !CancelCopy() )
02227 {
02228 #ifdef RIO_DEBUG2
02229 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02230 "Error when executing CancelCopy" );
02231 #endif
02232
02233 return false;
02234 }
02235
02236
02237 if( m_FileName != NULL )
02238 delete m_FileName;
02239
02240 if( !CloseRioObject() )
02241 {
02242 #ifdef RIO_DEBUG2
02243 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02244 "Error closing RioObject: %u (%s)", m_RioStatus,
02245 GetErrorDescription( m_RioStatus ).c_str() );
02246 #endif
02247
02248 return false;
02249 }
02250
02251 if( !CloseRioStream() )
02252 {
02253 #ifdef RIO_DEBUG2
02254 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02255 "Error closing RioStream: %u (%s)", m_RioStatus,
02256 GetErrorDescription( m_RioStatus ).c_str() );
02257 #endif
02258
02259 return false;
02260 }
02261
02262 return true;
02263 }
02264
02265
02266
02267
02268 bool CRioModule::ProcessNextBlock( bool *HasNextBlock )
02269 {
02270 bool isFirstBlock;
02271 RioBlock Block;
02272 RioObjectSize StartFirstBlock;
02273 char *Data;
02274 unsigned int DataSize;
02275 int status;
02276
02277
02278 *HasNextBlock = false;
02279
02280
02281 if( ( m_Object == NULL ) || ( !m_isObjectOpen ) )
02282 {
02283 if( m_Object == NULL )
02284 m_RioStatus = ERROR_RIOOBJECT + ERROR_NOT_INITIALIZED;
02285 else
02286 m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_NOT_OPENED;
02287
02288 #ifdef RIO_DEBUG2
02289 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02290 "No copy in progress: %u (%s)", m_RioStatus,
02291 GetErrorDescription( m_RioStatus ).c_str() );
02292 #endif
02293
02294 return false;
02295 }
02296
02297
02298 if( ( ( m_Access & RIO_READ_MASK ) != 0 ) &&
02299 ( ( m_Access & RIO_WRITE_MASK ) == 0 ) )
02300 {
02301
02302
02303 status = pthread_mutex_lock( &m_Mutex );
02304 if( status < 0 )
02305 {
02306 m_SystemStatus = status;
02307
02308 #ifdef RIO_DEBUG2
02309 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02310 "Error locking m_Mutex: %u (%s)",
02311 m_SystemStatus, strerror( m_SystemStatus ) );
02312 #endif
02313
02314
02315 if( !CancelCopy() )
02316 {
02317 #ifdef RIO_DEBUG2
02318 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02319 "Error when executing CancelCopy" );
02320 #endif
02321
02322 return false;
02323 }
02324
02325 return false;
02326 }
02327
02328 if( m_SendBlock < m_TotalBlocks )
02329 {
02330 Block = m_SendBlock;
02331 m_SendBlock++;
02332 isFirstBlock = m_isFirstBlock;
02333 m_isFirstBlock = false;
02334 StartFirstBlock = m_StartFirstBlock;
02335 m_StartFirstBlock = 0;
02336 }
02337 else
02338 {
02339
02340
02341 #ifdef RIO_DEBUG2
02342 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02343 "No copy in progress" );
02344 #endif
02345
02346
02347
02348 status = pthread_mutex_unlock( &m_Mutex );
02349 if( status < 0 )
02350 {
02351 m_SystemStatus = status;
02352
02353 #ifdef RIO_DEBUG2
02354 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02355 "Error unlocking m_Mutex: %u (%s)",
02356 m_SystemStatus, strerror( m_SystemStatus ) );
02357 #endif
02358
02359 }
02360
02361 *HasNextBlock = false;
02362
02363
02364 if( !CancelCopy() )
02365 {
02366 #ifdef RIO_DEBUG2
02367 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02368 "Error when executing CancelCopy" );
02369 #endif
02370
02371 return false;
02372 }
02373
02374 return false;
02375
02376 }
02377
02378 #ifdef RIO_DEBUG2
02379 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02380 "Trying to copy block %u", m_SendBlock - 1 );
02381 #endif
02382
02383 *HasNextBlock = ( m_SendBlock < m_TotalBlocks );
02384
02385
02386 status = pthread_mutex_unlock( &m_Mutex );
02387 if( status < 0 )
02388 {
02389 m_SystemStatus = status;
02390
02391 #ifdef RIO_DEBUG2
02392 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02393 "Error unlocking m_Mutex: %u (%s)",
02394 m_SystemStatus, strerror( m_SystemStatus ) );
02395 #endif
02396
02397
02398 if( !CancelCopy() )
02399 {
02400 #ifdef RIO_DEBUG2
02401 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02402 "Error when executing CancelCopy" );
02403 #endif
02404
02405 return false;
02406 }
02407
02408 return false;
02409 }
02410
02411
02412
02413 if( !m_CircularBuffer->GetElement( m_ApacheBuffer ) )
02414 {
02415 m_SystemStatus = m_CircularBuffer->GetError();
02416
02417 #ifdef RIO_DEBUG2
02418 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02419 "Error reading block %u from circular buffer: %u (%s)",
02420 Block, m_SystemStatus, strerror( m_SystemStatus ) );
02421 #endif
02422
02423
02424 if( !CancelCopy() )
02425 {
02426 #ifdef RIO_DEBUG2
02427 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02428 "Error when executing CancelCopy" );
02429 #endif
02430
02431 return false;
02432 }
02433
02434 return false;
02435 }
02436
02437
02438 if( isFirstBlock )
02439 {
02440 Data = &m_ApacheBuffer[ StartFirstBlock ];
02441 if( *HasNextBlock )
02442 {
02443
02444
02445 DataSize = m_BlockSize - StartFirstBlock;
02446 }
02447 else
02448 DataSize = m_EndPosition - StartFirstBlock + 1;
02449 }
02450 else
02451 {
02452
02453
02454
02455
02456 Data = m_ApacheBuffer;
02457 if( *HasNextBlock )
02458 DataSize = m_BlockSize;
02459 else
02460 DataSize = m_EndPosition - ( ( m_TotalBlocks - 1 ) *
02461 m_BlockSize ) + 1;
02462 }
02463
02464
02465 if( !SendBlock( Data, DataSize ) )
02466 {
02467 #ifdef RIO_DEBUG2
02468 ap_log_rerror( APLOG_MARK, APLOG_ERR, m_ApacheStatus, m_Request,
02469 "Error sending block %u to the client", Block );
02470 #endif
02471
02472
02473 if( !CancelCopy() )
02474 {
02475 #ifdef RIO_DEBUG2
02476 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02477 "Error when executing CancelCopy" );
02478 #endif
02479
02480 return false;
02481 }
02482
02483 return false;
02484 }
02485
02486
02487
02488 if( !( *HasNextBlock ) )
02489 {
02490 if( !TerminateCopyToClient() )
02491 {
02492 #ifdef RIO_DEBUG2
02493 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02494 "Error when executing TerminateCopyToClient" );
02495 #endif
02496
02497 return false;
02498 }
02499 }
02500
02501 }
02502 else if( ( ( m_Access & RIO_READ_MASK ) == 0 ) &&
02503 ( ( m_Access & RIO_WRITE_MASK ) != 0 ) )
02504 {
02505
02506 }
02507 else
02508 {
02509
02510 m_RioStatus = ERROR_RIOOBJECT + ERROR_INVALID_ACCESS_TYPE;
02511
02512 #ifdef RIO_DEBUG2
02513 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02514 "Invalid access type: %u (%s)", m_RioStatus,
02515 GetErrorDescription( m_RioStatus ).c_str() );
02516 #endif
02517
02518
02519 if( !CancelCopy() )
02520 {
02521 #ifdef RIO_DEBUG2
02522 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02523 "Error when executing CancelCopy" );
02524 #endif
02525
02526 return false;
02527 }
02528
02529 return false;
02530 }
02531
02532 return true;
02533 }
02534
02535
02536 bool CRioModule::JumpToPosition( RioObjectSize StartPosition )
02537 {
02538 int status;
02539
02540
02541 if( ( m_Object == NULL ) || ( !m_isObjectOpen ) )
02542 {
02543 if( m_Object == NULL )
02544 m_RioStatus = ERROR_RIOOBJECT + ERROR_NOT_INITIALIZED;
02545 else
02546 m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_NOT_OPENED;
02547
02548 #ifdef RIO_DEBUG2
02549 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02550 "No copy in progress: %u (%s)", m_RioStatus,
02551 GetErrorDescription( m_RioStatus ).c_str() );
02552 #endif
02553
02554 return false;
02555 }
02556
02557
02558 if( ( ( m_Access & RIO_READ_MASK ) == 0 ) ||
02559 ( ( m_Access & RIO_WRITE_MASK ) != 0 ) )
02560 {
02561 m_RioStatus = ERROR_RIOOBJECT + ERROR_INVALID_ACCESS_TYPE;
02562
02563 #ifdef RIO_DEBUG2
02564 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02565 "Not sending a file to a client: %u (%s)", m_RioStatus,
02566 GetErrorDescription( m_RioStatus ).c_str() );
02567 #endif
02568
02569 return false;
02570 }
02571
02572
02573 if( !CancelCopy() )
02574 {
02575 #ifdef RIO_DEBUG2
02576 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02577 "Error when executing CancelCopy" );
02578 #endif
02579
02580 return false;
02581 }
02582
02583
02584 status = pthread_mutex_lock( &m_Mutex );
02585 if( status < 0 )
02586 {
02587 m_SystemStatus = status;
02588
02589 #ifdef RIO_DEBUG2
02590 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02591 "Error locking m_Mutex: %u (%s)",
02592 m_SystemStatus, strerror( m_SystemStatus ) );
02593 #endif
02594
02595 return false;
02596 }
02597
02598
02599 m_RioBlock = StartPosition / m_BlockSize;
02600 m_SendBlock = m_RioBlock;
02601
02602
02603 m_StartFirstBlock = StartPosition % m_BlockSize;
02604
02605
02606
02607 m_isFirstBlock = true;
02608
02609
02610 m_isReadingFile = true;
02611
02612
02613 status = pthread_mutex_unlock( &m_Mutex );
02614 if( status < 0 )
02615 {
02616 m_SystemStatus = status;
02617
02618 #ifdef RIO_DEBUG2
02619 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02620 "Error unlocking m_Mutex: %u (%s)",
02621 m_SystemStatus, strerror( m_SystemStatus ) );
02622 #endif
02623
02624 return false;
02625 }
02626
02627
02628 ap_set_content_length( m_Request, m_FileSize - StartPosition );
02629
02630 return true;
02631 }
02632
02633
02634
02635 void CRioModule::GetErrors( apr_status_t *ApacheStatus, int *SystemStatus,
02636 RioResult *RioStatus )
02637 {
02638 *ApacheStatus = m_ApacheStatus;
02639 *SystemStatus = m_SystemStatus;
02640 *RioStatus = m_RioStatus;
02641 }
02642
02643
02644
02645 bool CRioModule::NoError()
02646 {
02647 return( ( m_ApacheStatus == APR_SUCCESS) && ( m_SystemStatus == 0 ) &&
02648 ( m_RioStatus == S_OK ) );
02649 }
02650
02651
02652 bool CRioModule::SendSignal()
02653 {
02654 int status;
02655
02656
02657 status = pthread_mutex_lock( &m_ReadMutex );
02658 if( status != 0 )
02659 {
02660 m_SystemStatus = status;
02661
02662 #ifdef RIO_DEBUG2
02663 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02664 "Error locking mutex m_ReadMutex: %u (%s)",
02665 m_SystemStatus, strerror( m_SystemStatus ) );
02666 #endif
02667
02668 return false;
02669 }
02670
02671
02672
02673 status = pthread_cond_signal( &m_ReadCond );
02674 if( status < 0 )
02675 {
02676 m_SystemStatus = status;
02677
02678 #ifdef RIO_DEBUG2
02679 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02680 "Error sending signal: %u (%s)", m_SystemStatus,
02681 strerror( m_SystemStatus ) );
02682 #endif
02683
02684 return false;
02685 }
02686
02687
02688 status = pthread_mutex_unlock( &m_ReadMutex );
02689 if( status != 0 )
02690 {
02691 m_SystemStatus = status;
02692
02693 #ifdef RIO_DEBUG2
02694 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request,
02695 "Error unlocking mutex m_ReadMutex: %u (%s)",
02696 m_SystemStatus, strerror( m_SystemStatus ) );
02697 #endif
02698
02699 return false;
02700 }
02701
02702 return true;
02703 }
02704
02705
02706 request_rec *CRioModule::GetRequest()
02707 {
02708 return m_Request;
02709 }