#include <RioModule.h>
Public Member Functions | |
CRioModule (request_rec *Request) | |
Construtor da classe RioModule, para criar um novo objeto desta classe. | |
~CRioModule () | |
Destrutor da classe RioModule, usado quando um objeto e removido. | |
bool | Start (char *ServerName, char *UserName, char *UserPassword, unsigned int BufferSize, unsigned int FragmentSize, unsigned int *BlockSize) |
Funcao para inicializar o objeto da classe RioModule (ou seja, abrir a conexao e o stream). | |
bool | Stop () |
bool | Open (const char *FileName, RioAccess Access, bool UseRealTime, unsigned int WaitTime, RioObjectSize StartPosition, RioObjectSize EndPosition, bool SendHeader, RioObjectSize *FileSize, unsigned int *TotalBlocks) |
Funcao para abrir um arquivo do servidor RIO para copiar os seus blocos. | |
bool | Close () |
Funcao para fechar o ultimo arquivo aberto, terminando qualquer copia em andamento. | |
bool | ProcessNextBlock (bool *HasNextBlock) |
Funcao para ler e depois enviar o proximo bloco do arquivo para o cliente, ou receber o proximo bloco do cliente e depois grava-lo no arquivo. | |
bool | JumpToPosition (RioObjectSize StartPosition) |
Funcao para saltar para um outro ponto do arquivo. | |
void | GetErrors (apr_status_t *ApacheStatus, int *SystemStatus, RioResult *RioStatus) |
Funcao para copiar um arquivo (aberto pela funcao open para escrita) do apache para o servidor RIO. | |
bool | NoError () |
Funcao para verificar se algum erro ocorreu ao executarmos uma das funcoes da classe. | |
bool | SendSignal () |
Funcao para gerar um sinal para a variavel de condicao m_CopyCond (esta funcao e usada pela callback chamada apos o recebimento de um bloco). | |
request_rec * | GetRequest () |
Funcao para obter um ponteiro para a requisicao HTTP associada a copia. | |
Private Member Functions | |
bool | SendBlock (const char *Data, unsigned int DataSize) |
Funcao para enviar dados ao cliente, armazenados no buffer passado no parametro Data. | |
bool | ReceiveBlock (char *Data, unsigned int DataSize) |
Funcao para receber dados do cliente, os armazenando no buffer passado no parametro Data, sendo que no maximo DataSize bytes serao recebidos. | |
bool | TerminateCopyToClient () |
Funcao para terminar o envio de dados ao client. | |
bool | OpenRioSession (char *ServerName, char *UserName, char *UserPassword) |
Funcao para abrir a sessao com o servidor RIO, com o servidor dado pelo parametro m_ServerName. | |
bool | CloseRioSession () |
Funcao para fechar a sessao apontada por m_Session. | |
bool | OpenRioStream (bool UseRealTime, RioStreamDirection Direction) |
Funcao para abrir um stream associado a sessao apontada pelo ponteiro m_Session. | |
bool | CloseRioStream () |
bool | OpenRioObject (char *FileName, RioAccess Access) |
bool | CloseRioObject () |
bool | ReadRioObjectBlock (RioBlock Block) |
bool | WriteRioObjectBlock (RioBlock Block) |
bool | CancelCopy () |
Funcao para cancelar a copia. | |
bool | SendFileHeader (const char *FileName) |
Funcao para enviar um cabecalho antes dos dados do arquivo, caso o arquivo necessite do envio deste cabecalho. | |
Static Private Member Functions | |
static void * | ReadThreadFunction (void *Class) |
Funcao usada pela thread que copia os blocos. | |
Private Attributes | |
bool | m_Started |
request_rec * | m_Request |
CRioSession * | m_Session |
bool | m_isSessionOpen |
CRioStream * | m_Stream |
bool | m_isStreamOpen |
CRioObject * | m_Object |
bool | m_isObjectOpen |
bool | m_UseRealTime |
int | m_WaitTime |
char * | m_ServerName |
char * | m_FileName |
RioAccess | m_Access |
RioObjectSize | m_FileSize |
apr_status_t | m_ApacheStatus |
int | m_SystemStatus |
RioResult | m_RioStatus |
CircularBuffer * | m_CircularBuffer |
char * | m_RioBuffer |
char * | m_ApacheBuffer |
RioBlock | m_RioBlock |
RioBlock | m_SendBlock |
unsigned int | m_TotalBlocks |
unsigned int | m_BlockSize |
unsigned int | m_FragmentSize |
RioObjectSize | m_StartFirstBlock |
RioObjectSize | m_EndPosition |
bool | m_isFirstBlock |
bool | m_isReadingFile |
pthread_cond_t | m_ReadStarted |
pthread_cond_t | m_ThreadBlocked |
pthread_mutex_t | m_ReadMutex |
pthread_cond_t | m_ReadCond |
pthread_t | m_ReadThread |
bool | m_ThreadCanceled |
pthread_mutex_t | m_Mutex |
Definition at line 36 of file RioModule.h.
CRioModule::CRioModule | ( | request_rec * | Request | ) |
Construtor da classe RioModule, para criar um novo objeto desta classe.
Request | ponteiro para a requisicao associada a conexao http com o cliente. |
Definition at line 37 of file RioModule.cpp.
00038 { 00039 int status; 00040 // Inicializa as variaveis da classe passadas ao criarmos o objeto. 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 // Inicializa os codigos de erro. 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 }
CRioModule::~CRioModule | ( | ) |
Destrutor da classe RioModule, usado quando um objeto e removido.
Definition at line 144 of file RioModule.cpp.
00145 { 00146 int status; 00147 // Para o objeto, se ele ja foi inicializado e nao foi parado depois 00148 // disso. 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 }
bool CRioModule::CancelCopy | ( | ) | [private] |
Funcao para cancelar a copia.
Definition at line 1368 of file RioModule.cpp.
01369 { 01370 int status; 01371 bool isReadingFile; 01372 01373 // Obtem o mutex para acessar exclusivamente as variaveis do buffer. 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 // Salva o valor anterior de m_isReadingFile, pois somente devemos esperar 01389 // caso a thread de copia estivesse copiando um arquivo. 01390 isReadingFile = m_isReadingFile; 01391 01392 // Altera as variaveis da copia para um estado que indica que nao estamos 01393 // mais copiando. 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 // Somente devemos esperar se uma copia estava em andamento, 01403 if( isReadingFile ) 01404 { 01405 // Remove quaiquer valores do Buffer circular, pois comecamos uma nova 01406 // copia. 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 // Envia o termino da copia, se nao tivermos mais blocos para serem 01416 // enviados. 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 // Espera que a thread fique bloqueada 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 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 }
bool CRioModule::Close | ( | ) |
Funcao para fechar o ultimo arquivo aberto, terminando qualquer copia em andamento.
Definition at line 2223 of file RioModule.cpp.
02224 { 02225 // Tentando cancelar a copia, se ela nao foi concluida. 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 // Remove o nome do arquivo. 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 }
bool CRioModule::CloseRioObject | ( | ) | [private] |
Definition at line 749 of file RioModule.cpp.
00750 { 00751 RioResult hResult; 00752 00753 // Verifica se o objeto e valido e esta aberto. 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 // Fecha o objeto 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 // Verifica se a stream e valida e se esta aberta. 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 // Remove o objeto com o arquivo. 00802 delete m_Object; 00803 00804 m_isObjectOpen = false; 00805 00806 return true; 00807 }
bool CRioModule::CloseRioSession | ( | ) | [private] |
Funcao para fechar a sessao apontada por m_Session.
Definition at line 475 of file RioModule.cpp.
00476 { 00477 RioResult hResult; 00478 00479 // Verifica se a sessao e valida e se esta aberta. 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 // Tenta fechar a sessao 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 // Remove o objeto com a sessao. 00512 delete m_Session; 00513 00514 m_isSessionOpen = false; 00515 00516 return true; 00517 }
bool CRioModule::CloseRioStream | ( | ) | [private] |
Definition at line 624 of file RioModule.cpp.
00625 { 00626 RioResult hResult; 00627 bool Status; 00628 00629 // Verifica se a stream e valida e se esta aberta. 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 // Tenta fechar o stream. 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 // Remove o objeto com o stream. 00668 delete m_Stream; 00669 00670 return Status; 00671 }
void CRioModule::GetErrors | ( | apr_status_t * | ApacheStatus, | |
int * | SystemStatus, | |||
RioResult * | RioStatus | |||
) |
Funcao para copiar um arquivo (aberto pela funcao open para escrita) do apache para o servidor RIO.
ApacheStatus | ponteiro para a variavel que recebera o codigo de erro retorado pelas funcoes do apache. | |
SystemStatus | ponteiro para a variavel que recebera o codigo de erro retornado pelas funcoes da biblioteca do sistema. | |
RioStatus | ponteiro para a variavel que recebera o codigo de erro retornado pelas funcoes do RIO. |
Definition at line 2635 of file RioModule.cpp.
02637 { 02638 *ApacheStatus = m_ApacheStatus; 02639 *SystemStatus = m_SystemStatus; 02640 *RioStatus = m_RioStatus; 02641 }
request_rec * CRioModule::GetRequest | ( | ) |
Funcao para obter um ponteiro para a requisicao HTTP associada a copia.
Definition at line 2706 of file RioModule.cpp.
02707 { 02708 return m_Request; 02709 }
bool CRioModule::JumpToPosition | ( | RioObjectSize | StartPosition | ) |
Funcao para saltar para um outro ponto do arquivo.
StartPosition | posicao inicial para onde desejamos saltar. |
Definition at line 2536 of file RioModule.cpp.
02537 { 02538 int status; 02539 02540 // Verifica se o objeto e valido e esta aberto. 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 // Verifica se estamos lendo um arquivo. 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 // Cancela a copia atual. 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 // Obtem o mutex para acessar exclusivamente as variaveis do buffer. 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 // Calcula o bloco inicial do arquivo a ser enviado. 02599 m_RioBlock = StartPosition / m_BlockSize; 02600 m_SendBlock = m_RioBlock; 02601 02602 // Calcula a posicao inicial dentro do primeiro bloco. 02603 m_StartFirstBlock = StartPosition % m_BlockSize; 02604 02605 // Define que o proximo bloco sera o primeiro bloco (esta variavel se 02606 // tornara false apos este bloco ser copiado) 02607 m_isFirstBlock = true; 02608 02609 // Informa que comecamos a copia do arquivo. 02610 m_isReadingFile = true; 02611 02612 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 // Envia para o cliente o tamanho do arquivo a ser enviado. 02628 ap_set_content_length( m_Request, m_FileSize - StartPosition ); 02629 02630 return true; 02631 }
bool CRioModule::NoError | ( | ) |
Funcao para verificar se algum erro ocorreu ao executarmos uma das funcoes da classe.
Definition at line 2645 of file RioModule.cpp.
02646 { 02647 return( ( m_ApacheStatus == APR_SUCCESS) && ( m_SystemStatus == 0 ) && 02648 ( m_RioStatus == S_OK ) ); 02649 }
bool CRioModule::Open | ( | const char * | FileName, | |
RioAccess | Access, | |||
bool | UseRealTime, | |||
unsigned int | WaitTime, | |||
RioObjectSize | StartPosition, | |||
RioObjectSize | EndPosition, | |||
bool | SendHeader, | |||
RioObjectSize * | FileSize, | |||
unsigned int * | TotalBlocks | |||
) |
Funcao para abrir um arquivo do servidor RIO para copiar os seus blocos.
O tipo de transmissao (tempo real ou nao) dependera do servidor escolhido ao inicializarmos o objeto. Obs: Os outros parametros da funcao (alem de FileName e Access), somente serao usados se estivermos transferindo um arquivo do servidor para o cliente.
FileName | nome do arquivo a ser aberto. | |
Access | tipo de acesso desejado ao objeto. | |
UseRealTime | valor booleano que, se true, indica que a copia do arquivo devera ser feita em tempo real. | |
WaitTime | tempo de espera por cada bloco, em milisegundos, se o arquivo for copiado em tempo real. | |
StartPosition | posicao inicial do arquivo da qual a copia deve ser comecada. Se StartPosition for positivo, entao as posicoes serao contadas a partir do inicio do arquivo. Porem, se o valor for negativo, as posicoes serao contadas a partir do final do arquivo (o valor usado para implementarmos o cabecalho Range do HTTP). | |
EndPosition | posicao do byte final a ser enviado. Se EndPosition for igual a -1, entao o arquivo sera enviado da posicao obtida ao processar StartPosition ate o seu ultimo byte. | |
SendHeader | true se devemos enviar o cabecalho ou false em caso contrario. | |
FileSize | ponteiro para o tipo RioObjectSize usado para armazenar o tamanho do arquivo. | |
TotalBlocks | ponteiro para um inteiro nao sinalizado usado para armazenar o numero de blocos do arquivo. |
Definition at line 1838 of file RioModule.cpp.
01842 { 01843 RioResult hResult; 01844 int status; 01845 RioStreamDirection Direction; 01846 01847 // Inicializa os parametros FileSize e TotalBlocks. 01848 *FileSize = 0; 01849 *TotalBlocks = 0; 01850 01851 // Obtem o mutex para acessar exclusivamente as variaveis do buffer. 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 // Verifica se uma copia esta em progresso. 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 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 // Salva a informacao se as copias (leitura) devem ou nao ser em tempo 01906 // real. 01907 m_UseRealTime = UseRealTime; 01908 01909 // Inicializa a variavel com o tipo de acesso. 01910 m_Access = Access; 01911 01912 // Verifica se o acesso e valido 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 // Inicializa a direcao do stream. 01930 if( ( m_Access & RIO_READ_MASK ) != 0 ) 01931 Direction = RioStreamDirectionRead; // Leitura. 01932 else 01933 Direction = RioStreamDirectionWrite; // Escrita. 01934 01935 // Tenta copiar o nome do arquivo. 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 // Abre o stream associado ao modulo. 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 // Tenta abrir o arquivo que desejamos ler. 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 // Se o acesso for para leitura, devemos ler o tamanho do arquivo e 01990 // inicializar a copia. 01991 if( ( m_Access & RIO_READ_MASK ) != 0 ) 01992 { 01993 // Tenta obter o tamanho do arquivo. 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 // Verifica se a posicao inicial e valida (se e maior do que o 02010 // tamanho do arquivo). 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 // Verifica se precisamos ajustar o valor de StartPosition. Se o valor 02027 // for negativo, o valor real que deveremos usar e 02028 // m_FileSize + StartPosition ("+" porque o valor e negativo), pois 02029 // neste caso estamos contando as posicoes a partir do final. 02030 if( StartPosition < 0 ) 02031 StartPosition = m_FileSize + StartPosition; 02032 02033 // Verifica se a posicao final e valida (se e maior do que o 02034 // tamanho do arquivo). 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 // Verifica se a posical final e menor do que a inicial. 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 // Verifica se devemos enviar o arquivo de StartPosition ate o seu 02063 // final, se EndPosition for igual a -1, ou ate EndPosition em caso 02064 // contrario. 02065 if( EndPosition == -1 ) 02066 { 02067 // Ajusta a posicao final para m_FileSize - 1. 02068 EndPosition = m_FileSize - 1; 02069 } 02070 02071 // Obtem o mutex para acessar exclusivamente as variaveis do buffer. 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 // Define o tempo de espera por cada bloco (leitura). Se WaitTime for 02087 // igual a o, o tempo deve ser calculado a partir da taxa de 02088 // transmissao do arquivo. Se diferente de 0, este tempo sera o usado. 02089 if( WaitTime != 0 ) 02090 m_WaitTime = WaitTime; 02091 else 02092 { 02093 // Variaveis usadas para calcular o tempo. 02094 unsigned long long int Numerator, Denominator; 02095 // Variavel usada para armazenar a taxa de transmissao. 02096 unsigned int VideoRate; 02097 02098 // Obtem a taxa de transmisssao do video. 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 // Computa o tempo para a taxa de transmissao dada (usando a 02117 // equacao que definimos). 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 // Calcula o numero de blocos. 02142 m_TotalBlocks = ( EndPosition + m_BlockSize ) / m_BlockSize; 02143 02144 // Calcula o bloco inicial do arquivo a ser enviado. 02145 m_RioBlock = StartPosition / m_BlockSize; 02146 m_SendBlock = m_RioBlock; 02147 02148 // Calcula a posicao inicial dentro do primeiro bloco. 02149 m_StartFirstBlock = StartPosition % m_BlockSize; 02150 02151 // Salva a posicao do ultimo byte a ser enviado. 02152 m_EndPosition = EndPosition; 02153 02154 // Define que o proximo bloco sera o primeiro bloco (esta variavel se 02155 // tornara false apos este bloco ser copiado) 02156 m_isFirstBlock = true; 02157 02158 // Informa que comecamos a copia do arquivo. 02159 m_isReadingFile = true; 02160 02161 // Inicializa o parametros FileSize e TotalBlocks. 02162 *FileSize = m_FileSize; 02163 *TotalBlocks = m_TotalBlocks; 02164 02165 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 // Envia um sinal para desbloquear a thread, pois iniciamos uma copia 02181 // de dados. 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 // Envia para o cliente o tamanho do arquivo a ser enviado. 02197 ap_set_content_length( m_Request, EndPosition - StartPosition + 1 ); 02198 02199 // Verifica se devemos enviar o cabecalho (isso somente ocorrera se 02200 // StartPosition for maior do que 0, SendHeader for true, e o arquivo 02201 // for um dos arquivos para os quais precisamos enviar um cabecalho 02202 // neste caso). 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 }
bool CRioModule::OpenRioObject | ( | char * | FileName, | |
RioAccess | Access | |||
) | [private] |
Definition at line 674 of file RioModule.cpp.
00675 { 00676 RioResult hResult; 00677 00678 // Verifica se o objeto passado como parametro e valido. 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 // Verifica se a stream e valida e esta aberta. 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 // Cria o objeto que sera usado para ler o arquivo. 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 // Abre, no servidor, o arquivo associado ao objeto. 00726 // RIO_READ_ACCESS | RIO_SHARE_READ 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 }
bool CRioModule::OpenRioSession | ( | char * | ServerName, | |
char * | UserName, | |||
char * | UserPassword | |||
) | [private] |
Funcao para abrir a sessao com o servidor RIO, com o servidor dado pelo parametro m_ServerName.
ServerName | ponteiro para o nome do servidor RIO. | |
UserName | ponteiro para o nome do usuario do RIO. | |
UserPassword | ponteiro para a senha do usuario apontado por UserName. |
Definition at line 418 of file RioModule.cpp.
00420 { 00421 RioResult hResult; 00422 00423 // Verifica se a sessao ja foi aberta. 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 // Cria o objeto que sera usado para criarmos a sessao com o RIO. 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 // Tenta se conectar ao servidor RIO (o valor 1 no ultimo parametro 00454 // indica que desejamos se conectar ao servidor RIO, ao inves da RIOPL). 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 }
bool CRioModule::OpenRioStream | ( | bool | UseRealTime, | |
RioStreamDirection | Direction | |||
) | [private] |
Funcao para abrir um stream associado a sessao apontada pelo ponteiro m_Session.
Definition at line 520 of file RioModule.cpp.
00521 { 00522 RioStreamTraffic Traffic; 00523 RioResult hResult; 00524 //CRioStream *Stream; 00525 // 187,500 bytes/sec = 1,500,000 bits/sec (Default: assumes 1.5 Mbit/sec). 00526 // Obs: copiado de RioMMClient.cpp. 00527 double Rate = 187.5e+03; 00528 // Numero maximo de requisicoes (trafego de tempo nao real). 00529 // Obs: Copiado de RioExplorer.cpp. 00530 static const int MaxRequests = 20; 00531 00532 // Verifica se a stream ja esta aberta. 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 // Verifica se a sessao e valida e esta aberta. 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 // Cria o stream usado para copiar os arquivos. 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 // Inicializa os dados do stream. 00581 if( UseRealTime ) 00582 { 00583 Traffic.Type = RIO_TRAFFIC_VBR; 00584 Traffic.MaxRequests = 1; // Ignored in new version of RIO. 00585 // Reserve extra rate to absorb fluctuations on stream rate. 00586 // Guessing 50% extra should be enough. 00587 // Obs: copiado de RioMMClient.cpp. 00588 Rate = Rate * 1.5; 00589 // Obs: a linha a seguir (copiada da funcao Connect de RioMMClient.cpp) 00590 // esta correta? Nao seria a seguinte, ou nao tem diferenca? 00591 //Traffic.TrafficCBR.Rate = Rate; 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; // RioStreamDirectionRead 00601 Traffic.LogicalBlockSize = m_BlockSize; 00602 00603 // Abre o stream 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 }
bool CRioModule::ProcessNextBlock | ( | bool * | HasNextBlock | ) |
Funcao para ler e depois enviar o proximo bloco do arquivo para o cliente, ou receber o proximo bloco do cliente e depois grava-lo no arquivo.
A operacao executada dependera do parametro Access passado ao abrir o arquivo.
HasNextBlock | true se existe mais um bloco para ser copiado ou false caso nao existam mais blocos para serem copiados. |
Definition at line 2268 of file RioModule.cpp.
02269 { 02270 bool isFirstBlock; 02271 RioBlock Block; 02272 RioObjectSize StartFirstBlock; 02273 char *Data; 02274 unsigned int DataSize; 02275 int status; 02276 02277 // Inicializa o paramatro HasNextBlock. 02278 *HasNextBlock = false; 02279 02280 // Verifica se o objeto e valido e esta aberto. 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 // Verifica a direcao da copia. 02298 if( ( ( m_Access & RIO_READ_MASK ) != 0 ) && 02299 ( ( m_Access & RIO_WRITE_MASK ) == 0 ) ) 02300 { 02301 // O acesso e para enviar um arquivo do servidor para o cliente. 02302 // Obtem o mutex para acessar exclusivamente as variaveis do buffer. 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 // Cancela a copia atual. 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 // Se m_SendBlock for igual a m_TotalBlocks, entao a copia ja foi 02340 // finalizada. 02341 #ifdef RIO_DEBUG2 02342 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, 02343 "No copy in progress" ); 02344 #endif 02345 02346 // Libera o mutex para acessar exclusivamente as variaveis do 02347 // buffer. 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 // Cancela a copia atual. 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 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 // Cancela a copia atual. 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 // Obtem o proximo bloco do buffer circular. 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 // Cancela a copia atual. 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 // Descobre o que deve ser copiado 02438 if( isFirstBlock ) 02439 { 02440 Data = &m_ApacheBuffer[ StartFirstBlock ]; 02441 if( *HasNextBlock ) 02442 { 02443 // Se e o primeiro bloco, deveremos pular os primeiros bytes, se 02444 // necessario (isso dependera do deslocamento inicial). 02445 DataSize = m_BlockSize - StartFirstBlock; 02446 } 02447 else 02448 DataSize = m_EndPosition - StartFirstBlock + 1; 02449 } 02450 else 02451 { 02452 // Se nao e o primeiro bloco, deveremos sempre comecar do inicio do 02453 // bloco mas, se este for o ultimo bloco, vamos copiar somente a 02454 // parte inicial do bloco (o bloco somente sera todo copiado se o 02455 // tamanho do arquivo for multiplo do tamanho do bloco). 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 // Envia os dados para o cliente. 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 // Cancela a copia atual. 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 // Envia o termino da copia, se nao tivermos mais blocos para serem 02487 // enviados. 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 // O acesso e para receber um arquivo cliente e envia-lo ao servidor. 02506 } 02507 else 02508 { 02509 // O acesso e invalido. 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 // Cancela a copia atual. 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 }
bool CRioModule::ReadRioObjectBlock | ( | RioBlock | Block | ) | [private] |
Definition at line 827 of file RioModule.cpp.
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 // Numero de tentativas de ler um bloco (devemos considerar isso?) 00842 unsigned int numberofretrys = 0; 00843 00844 // Verifica se o objeto e valido e esta aberto. 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 // Inicializa a estrutura com o pedido do bloco. 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 // Espera pela leitura do bloco (o que fazer no caso de tempo real?) 00876 // Se a copia for em tempo nao-real, devemos esperar pela chegada 00877 // do bloco. 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 // Verifica se a copia do bloco (total ou parcial) ocorreu com 00952 // sucesso. 00953 if( Request.Result == S_OK ) 00954 { 00955 CopyBlock = false; 00956 } 00957 else if( ( Request.Result & 0xFF ) == 00958 ERROR_SERVICE_TEMPORARY_UNAVAILABLE ) 00959 { 00960 // Obs: O 0xFF acima (com o AND logico) e para somente 00961 // considerar o codigo de erro geral, desconsiderando a parte do 00962 // erro que identifica a clase (AND - & - com 0xFF00) e o codigo 00963 // 0xE000 do RIO (obtido com AND - & - 0xFFFF0000). Neste caso, 00964 // o servidor caiu ao requisitarmos o bloco. Tentaremos ler 00965 // novamente o bloco se o numero de tentativas nao expirou. 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 // Obtem o endereco e a porta do servidor. 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 // Esperar por alguns milisegundos pelo bloco (definidos no arquivo de 01040 // configuracao do modulo). 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 // Espera pelo recebimento do bloco. 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 // Esta e a reqid correta? 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 // Se hResult >= 0, entao temos em hResult o tamanho do bloco lido, 01125 // sem erros. A callback somente e chamada pela FreeBlock se algum 01126 // byte do bloco foi recebido com sucesso. Em caso contrario, o 01127 // NetBuf e removido da lista de processamento. Logo, deveremos 01128 // bloquear esperando pela callback se chamada somente quando 01129 // hResult > 0. 01130 if( hResult > 0 ) // A callback foi chamada 01131 { 01132 // Espera pela callback ser chamada. 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 // Verifica se o resultado foi correto ou errado. 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 }
void * CRioModule::ReadThreadFunction | ( | void * | Class | ) | [static, private] |
Funcao usada pela thread que copia os blocos.
Class | ponteiro para o objeto da classe que criou a thread. |
Definition at line 1224 of file RioModule.cpp.
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 // Executa ate que um erro ocorra ou que seja informado que a thread deve 01239 // terminar a sua execucao. 01240 while( 1 ) 01241 { 01242 // Verifica se a thread deve terminar a sua execucao. 01243 if( Module->m_ThreadCanceled ) 01244 return NULL; 01245 01246 // Obtem o mutex para acessar exclusivamente as variaveis do buffer 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 // Informa as outra thread que a thread esta esperando para iniciar 01254 // a copia. 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 // Verifica se uma copia esta em andamento. Caso nao esteja, espera 01263 // na variavel de condicao m_ReadStarted ate uma copia ser iniciada. 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 // Copia o valor do proximo bloco. 01280 Block = Module->m_RioBlock; 01281 01282 // Libera o mutex para acessar exclusivamente as variaveis do 01283 // buffer. 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 // Tenta ler o bloco do servidor RIO. 01292 NoError = Module->ReadRioObjectBlock( Block ); 01293 01294 // usleep( 500000 ); // Espera por 500ms=0,5s apos pedir o bloco. 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 // Tenta inserir o bloco lido no buffer circular. 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 // Obtem novamente o mutex para acessar exclusivamente as 01330 // variaveis do buffer. 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 // Incrementa o Module->m_RioBlock para apontar para o proximo 01339 // bloco. 01340 Module->m_RioBlock++; 01341 // Verifica se ja todos os blocos ja foram lidos. Se isso ja 01342 // ocorreu, entao devemos cancelar a leitura. 01343 if( ( Module->m_RioBlock >= Module->m_TotalBlocks ) || 01344 ( !NoError ) ) 01345 { 01346 // Se algum erro ocorreu ou a copia terminou, entao deveremos 01347 // indicar o termino da copia. 01348 Module->m_isReadingFile = false; 01349 // Se um erro ocorreu, deveremos tambem desbloquear a thread 01350 // que repassa os blocos para o apache, se ela estiver 01351 // bloqueada no buffer circular esperando por elementos. 01352 if( !NoError ) 01353 Module->m_CircularBuffer->CancelGetElement(); 01354 01355 } 01356 } 01357 // Libera o mutex para acessar exclusivamente as variaveis do buffer. 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 }
bool CRioModule::ReceiveBlock | ( | char * | Data, | |
unsigned int | DataSize | |||
) | [private] |
Funcao para receber dados do cliente, os armazenando no buffer passado no parametro Data, sendo que no maximo DataSize bytes serao recebidos.
Data | ponteiro para o buffer com os dados (o bloco atual). | |
DataSize | ponteiro para o tamanho maximo dos dados. Este parametro sera alterado pela funcao para o numero de bytes realmente lidos do cliente (este valor pode ser menor do que o valor passado, se o cliente enviou menos dados do que o desejado). |
Definition at line 346 of file RioModule.cpp.
bool CRioModule::SendBlock | ( | const char * | Data, | |
unsigned int | DataSize | |||
) | [private] |
Funcao para enviar dados ao cliente, armazenados no buffer passado no parametro Data.
O numero de bytes e dado em DataSize. Os dados serao enviados em fragmentos de tamanho de no maximo m_FragmentSize bytes (note que o ultimo fragmento pode ser menor, caso DataSize nao seja multiplo de m_FragmentSize).
Data | ponteiro para o buffer com os dados (o bloco atual). | |
DataSize | tamanho dos dados (quando a implementacao estiver completa, este tamanho sera igual ao do bloco para os blocos intermediarios mas podera nao ser este tamanho para o bloco inicial - caso a copia nao comece no inicio do arquivo - e para o bloco final - pois o tamanho do arquivo nao e necessariamente multiplo do bloco-). |
Definition at line 205 of file RioModule.cpp.
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 // Envia o bloco para o cliente. 00214 // Verifica o tamanho de cada fragmento. 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 // Calcula o numero total de fragmentos. 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 // Determina o tamanho dos dados a serem enviados. 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 // Cria a estrutura de dados para enviar um fragmento. 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 // Envia o fragmento ao cliente. 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 // Cria um bucket para indicar o final do fragmento. 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 // Insere o bucket no final da brigade. 00300 APR_BRIGADE_INSERT_TAIL( bb, b ); 00301 00302 // Passa o fragmento ja escrito para os outros filtros 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 // Atualiza NextFragment para o proximo fragmento. 00338 NextFragment++; 00339 } 00340 00341 return true; 00342 }
bool CRioModule::SendFileHeader | ( | const char * | FileName | ) | [private] |
Funcao para enviar um cabecalho antes dos dados do arquivo, caso o arquivo necessite do envio deste cabecalho.
FileName | nome do arquivo que desejamos avaliar se o envio do cabecalho e necessario. |
Definition at line 1475 of file RioModule.cpp.
01476 { 01477 const char *StartFinalExtension; 01478 const char *Header; 01479 unsigned int HeaderSize; 01480 01481 // Procura pelo inicico da ultima extensao no nome do arquivo. 01482 StartFinalExtension = strrchr( FileName, '.' ); 01483 01484 // Se o arquivo possuir uma extensao, StartFinalExtension + 1 apontara 01485 // para o inicio da proxima extensao. 01486 if( StartFinalExtension != NULL ) 01487 { 01488 // Um dos arquivos para o qual precisamos enviar um cabecalho e um 01489 // video do flash. 01490 if( strcmp( StartFinalExtension + 1, "flv" ) == 0 ) 01491 { 01492 Header = FLVX_HEADER; 01493 HeaderSize = FLVX_HEADER_LEN; 01494 } 01495 else 01496 { 01497 // Por enquanto, somente enviaremos o cabecalho para os arquivos 01498 // .flv. 01499 Header = NULL; 01500 HeaderSize = 0; 01501 } 01502 01503 if( Header != NULL ) 01504 return SendBlock( Header, HeaderSize ); 01505 01506 } 01507 01508 return true; 01509 }
bool CRioModule::SendSignal | ( | ) |
Funcao para gerar um sinal para a variavel de condicao m_CopyCond (esta funcao e usada pela callback chamada apos o recebimento de um bloco).
Definition at line 2652 of file RioModule.cpp.
02653 { 02654 int status; 02655 02656 // Obtem o mutex m_ReadMutex. 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 // Gera o sinal para a variavel de condicao m_ReadCond, associadao ao 02672 // mutex m_ReadMutex. 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 // Libera o mutex m_ReadMutex. 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 }
bool CRioModule::Start | ( | char * | ServerName, | |
char * | UserName, | |||
char * | UserPassword, | |||
unsigned int | BufferSize, | |||
unsigned int | FragmentSize, | |||
unsigned int * | BlockSize | |||
) |
Funcao para inicializar o objeto da classe RioModule (ou seja, abrir a conexao e o stream).
ServerName | nome do servidor a que vamos nos conectar. | |
UserName | nome do usuario para o qual desejamos abrir uma sessao. | |
UserPassword | senha do usuario UserName no servidor. | |
BufferSize | numero de entradas do buffer de recepcao. | |
FragmentSize | tamanho dos fragmentos enviados ao cliente. | |
BlockSize | ponteiro para um inteiro nao sinalizado usado para armazenar o tamanho de cada bloco do servidor (que sera impresso no cabecalho do pedido). |
Definition at line 1512 of file RioModule.cpp.
01515 { 01516 RioResult hResult; 01517 int error; 01518 int status; 01519 01520 // Inicializa o parametro BlocoSize. 01521 *BlockSize = 0; 01522 01523 // Verifica se a classe ja foi inicializada. 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 // Salva o tamanho do fragmento. 01538 m_FragmentSize = FragmentSize; 01539 01540 // Copia o nome do servidor passado como parametro. 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 // Tenta abrir a sessao associada ao modulo. 01556 // Obs: devemos criar uma variavel, no modulo, indicando o usuario e a 01557 // senha, ou devemos obter isso do arquivo .rio e do arquivo de configuracao 01558 // (caso seja passado um nome a funcao)? 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 // Obtem o tamanho do bloco. 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 // Tenta criar o buffer que armazenara o ultimo bloco lido (ou escrito) no 01586 // RIO. 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 // Tenta criar o buffer que armazenara o ultimo bloco enviado (ou recebido) 01611 // do cliente 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 // Deleta os bufferes do bloco. 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 // Tenta criar um objeto da classe CircularBuffer, usada para armazenar os 01641 // blocos lidos. 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 // Deleta os bufferes do bloco. 01664 delete[] m_RioBuffer; 01665 m_RioBuffer = NULL; 01666 delete[] m_ApacheBuffer; 01667 m_ApacheBuffer = NULL; 01668 01669 // Deleta o buffer circular. 01670 delete m_CircularBuffer; 01671 m_CircularBuffer = NULL; 01672 01673 return false; 01674 } 01675 01676 // Verifica se a classe inicializou corretamente. 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 // Inicializa a variavel que informa que a thread nao deve ser cancelada. 01703 m_ThreadCanceled = false; 01704 01705 // Cria a thread que copia os blocos do RIO, um a um, apos o arquivo ser 01706 // aberto (devemos criar a thread com os mesmos atributos do RIO?) 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 // Deleta os bufferes do bloco. 01729 delete[] m_RioBuffer; 01730 m_RioBuffer = NULL; 01731 delete[] m_ApacheBuffer; 01732 m_ApacheBuffer = NULL; 01733 01734 // Deleta o buffer circular. 01735 delete m_CircularBuffer; 01736 m_CircularBuffer = NULL; 01737 01738 return false; 01739 01740 } 01741 01742 // Altera o valor de m_Initialized para indicar que a classe foi 01743 // inicializada com sucesso. 01744 m_Started = true; 01745 01746 // Inicializa o parametro com o tamanho do bloco. 01747 *BlockSize = m_BlockSize; 01748 01749 return true; 01750 }
bool CRioModule::Stop | ( | ) |
Definition at line 1753 of file RioModule.cpp.
01754 { 01755 int status; 01756 01757 // Verifica se a classe foi inicializada. 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 // Cancela a thread 01772 if( m_ReadThread != 0 ) 01773 { 01774 // Informa a thread de copia dos blocos que ela deve terminar a sua 01775 // execucao. 01776 m_ThreadCanceled = true; 01777 01778 // Envia um sinal para a thread desbloquerar, caso ela esteja bloqueada. 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 // Espera que a thread termine a sua execucao. 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 // Fecha o objeto (se aberto), o stream e a sessao. 01811 if( m_isObjectOpen ) 01812 Close(); 01813 01814 if( m_isSessionOpen ) 01815 CloseRioSession(); 01816 01817 // Remove o nome do servidor. 01818 if( m_ServerName != NULL ) 01819 delete m_ServerName; 01820 01821 // Deleta os bufferes do bloco. 01822 delete[] m_RioBuffer; 01823 m_RioBuffer = NULL; 01824 delete[] m_ApacheBuffer; 01825 m_ApacheBuffer = NULL; 01826 01827 // Deleta o buffer circular. 01828 delete m_CircularBuffer; 01829 m_CircularBuffer = NULL; 01830 01831 01832 m_Started = false; 01833 01834 return true; 01835 }
bool CRioModule::TerminateCopyToClient | ( | ) | [private] |
Funcao para terminar o envio de dados ao client.
Definition at line 352 of file RioModule.cpp.
00353 { 00354 apr_bucket_brigade *bb; 00355 apr_bucket *b; 00356 apr_status_t rv; 00357 00358 // Cria a estrutura de dados para cancelar o envio do arquivo ao cliente. 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 // Cria um bucket para indicar o final do arquivo. 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 // Insere o bucket no final da brigade. 00387 APR_BRIGADE_INSERT_TAIL( bb, b ); 00388 00389 // Passa o bloco ja escrito para os outros filtros 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 }
bool CRioModule::WriteRioObjectBlock | ( | RioBlock | Block | ) | [private] |
Definition at line 1218 of file RioModule.cpp.
RioAccess CRioModule::m_Access [private] |
Definition at line 69 of file RioModule.h.
char* CRioModule::m_ApacheBuffer [private] |
Definition at line 89 of file RioModule.h.
apr_status_t CRioModule::m_ApacheStatus [private] |
Definition at line 74 of file RioModule.h.
unsigned int CRioModule::m_BlockSize [private] |
Definition at line 98 of file RioModule.h.
CircularBuffer* CRioModule::m_CircularBuffer [private] |
Definition at line 82 of file RioModule.h.
RioObjectSize CRioModule::m_EndPosition [private] |
Definition at line 105 of file RioModule.h.
char* CRioModule::m_FileName [private] |
Definition at line 67 of file RioModule.h.
RioObjectSize CRioModule::m_FileSize [private] |
Definition at line 71 of file RioModule.h.
unsigned int CRioModule::m_FragmentSize [private] |
Definition at line 100 of file RioModule.h.
bool CRioModule::m_isFirstBlock [private] |
Definition at line 109 of file RioModule.h.
bool CRioModule::m_isObjectOpen [private] |
Definition at line 52 of file RioModule.h.
bool CRioModule::m_isReadingFile [private] |
Definition at line 111 of file RioModule.h.
bool CRioModule::m_isSessionOpen [private] |
Definition at line 44 of file RioModule.h.
bool CRioModule::m_isStreamOpen [private] |
Definition at line 48 of file RioModule.h.
pthread_mutex_t CRioModule::m_Mutex [private] |
Definition at line 132 of file RioModule.h.
CRioObject* CRioModule::m_Object [private] |
Definition at line 50 of file RioModule.h.
pthread_cond_t CRioModule::m_ReadCond [private] |
Definition at line 125 of file RioModule.h.
pthread_mutex_t CRioModule::m_ReadMutex [private] |
Definition at line 124 of file RioModule.h.
pthread_cond_t CRioModule::m_ReadStarted [private] |
Definition at line 114 of file RioModule.h.
pthread_t CRioModule::m_ReadThread [private] |
Definition at line 128 of file RioModule.h.
request_rec* CRioModule::m_Request [private] |
Definition at line 40 of file RioModule.h.
RioBlock CRioModule::m_RioBlock [private] |
Definition at line 92 of file RioModule.h.
char* CRioModule::m_RioBuffer [private] |
Definition at line 86 of file RioModule.h.
RioResult CRioModule::m_RioStatus [private] |
Definition at line 78 of file RioModule.h.
RioBlock CRioModule::m_SendBlock [private] |
Definition at line 94 of file RioModule.h.
char* CRioModule::m_ServerName [private] |
Definition at line 62 of file RioModule.h.
CRioSession* CRioModule::m_Session [private] |
Definition at line 42 of file RioModule.h.
bool CRioModule::m_Started [private] |
Definition at line 38 of file RioModule.h.
RioObjectSize CRioModule::m_StartFirstBlock [private] |
Definition at line 103 of file RioModule.h.
CRioStream* CRioModule::m_Stream [private] |
Definition at line 46 of file RioModule.h.
int CRioModule::m_SystemStatus [private] |
Definition at line 76 of file RioModule.h.
pthread_cond_t CRioModule::m_ThreadBlocked [private] |
Definition at line 118 of file RioModule.h.
bool CRioModule::m_ThreadCanceled [private] |
Definition at line 130 of file RioModule.h.
unsigned int CRioModule::m_TotalBlocks [private] |
Definition at line 96 of file RioModule.h.
bool CRioModule::m_UseRealTime [private] |
Definition at line 55 of file RioModule.h.
int CRioModule::m_WaitTime [private] |
Definition at line 58 of file RioModule.h.