CRioModule Class Reference

#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
CRioSessionm_Session
bool m_isSessionOpen
CRioStreamm_Stream
bool m_isStreamOpen
CRioObjectm_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
CircularBufferm_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

Detailed Description

Definition at line 36 of file RioModule.h.


Constructor & Destructor Documentation

CRioModule::CRioModule ( request_rec *  Request  ) 

Construtor da classe RioModule, para criar um novo objeto desta classe.

Parameters:
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 }


Member Function Documentation

bool CRioModule::CancelCopy (  )  [private]

Funcao para cancelar a copia.

Returns:
true se a copia foi cancelada com sucesso ou false se algum erro ocorreu ao 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.

Returns:
true se o arquivo foi fechado com sucesso ou false se algum erro ocorreu ao fecharmos o arquivo.

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.

Returns:
true se a sessao foi fechada com sucesso e false em caso contrario (neste caso, m_RioStatus indicara o erro que ocorreu).

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.

Returns:
true se o arquivo foi copiado com sucesso ou false em caso contrario. Funcao para retornar os codigos de erro caso alguma das funcoes acima retorne false.
Parameters:
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.

Returns:
ponteiro para a requisicao.

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.

Parameters:
StartPosition posicao inicial para onde desejamos saltar.
Returns:
true se a copia foi reiniciada, nesta posicao, com sucesso, ou false se algum erro ocorreu.

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.

Returns:
true se a funcao foi executada com sucesso ou false em caso contrario.

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.

Parameters:
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.
Returns:
true se o arquivo foi aberto com sucesso ou false se o arquivo nao foi aberto com sucesso.

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.

Parameters:
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.
Returns:
true se a sessao foi criada com sucesso e false em caso contrario (neste caso, m_RioStatus indicara o erro que ocorreu).

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.

Returns:
true se o stream foi criada com sucesso e false em caso contrario (neste caso, m_RioStatus indicara o erro que ocorreu).

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.

Parameters:
HasNextBlock true se existe mais um bloco para ser copiado ou false caso nao existam mais blocos para serem copiados.
Returns:
true se a copia do bloco atual foi completada com sucesso ou false se algum erro ocorreu durante esta copia.

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.

Parameters:
Class ponteiro para o objeto da classe que criou a thread.
Returns:
valor nulo.

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.

Parameters:
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).
Returns:
true se os dados foram recebidos com sucesso e false em caso contrario (neste caso, m_ApacheStatus indicara o erro que ocorreu).

Definition at line 346 of file RioModule.cpp.

00347 {
00348     return true;
00349 }

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).

Parameters:
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-).
Returns:
true se os dados foram enviados com sucesso e false em caso contrario (neste caso, m_ApacheStatus indicara o erro que ocorreu).

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.

Parameters:
FileName nome do arquivo que desejamos avaliar se o envio do cabecalho e necessario.
Returns:
true a funcao foi executada com sucesso e false, em caso contrario, ou seja, se foi necessario enviar o cabecalho mais um erro ocorreu ao fazermos isso.

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).

Returns:
true se o sinal foi enviado com sucesso e false se algum erro ocorreu ao enviar o sinal.

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).

Parameters:
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).
Returns:
true se a inicializacao do objeto foi completada com sucesso ou false em caso contrario.

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.

Returns:
true se a copia foi terminada com sucesso, ou false em caso contrario (neste caso, m_ApacheStatus indicara o erro que ocorreu).

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.

01219 {
01220     return true;
01221 }


Field Documentation

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.

Definition at line 82 of file RioModule.h.

Definition at line 105 of file RioModule.h.

char* CRioModule::m_FileName [private]

Definition at line 67 of file RioModule.h.

Definition at line 71 of file RioModule.h.

unsigned int CRioModule::m_FragmentSize [private]

Definition at line 100 of file RioModule.h.

Definition at line 109 of file RioModule.h.

Definition at line 52 of file RioModule.h.

Definition at line 111 of file RioModule.h.

Definition at line 44 of file RioModule.h.

Definition at line 48 of file RioModule.h.

pthread_mutex_t CRioModule::m_Mutex [private]

Definition at line 132 of file RioModule.h.

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.

Definition at line 92 of file RioModule.h.

char* CRioModule::m_RioBuffer [private]

Definition at line 86 of file RioModule.h.

Definition at line 78 of file RioModule.h.

Definition at line 94 of file RioModule.h.

char* CRioModule::m_ServerName [private]

Definition at line 62 of file RioModule.h.

Definition at line 42 of file RioModule.h.

bool CRioModule::m_Started [private]

Definition at line 38 of file RioModule.h.

Definition at line 103 of file RioModule.h.

Definition at line 46 of file RioModule.h.

Definition at line 76 of file RioModule.h.

pthread_cond_t CRioModule::m_ThreadBlocked [private]

Definition at line 118 of file RioModule.h.

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.


The documentation for this class was generated from the following files:
Generated on Wed Jul 4 16:03:32 2012 for RIO by  doxygen 1.6.3