00001 /* 00002 * Copyright (C) 2010, Edmundo Albuquerque de Souza e Silva. 00003 * 00004 * This file may be distributed under the terms of the Q Public License 00005 * as defined by Trolltech AS of Norway and appearing in the file 00006 * LICENSE.QPL included in the packaging of this file. 00007 * 00008 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING 00009 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00010 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, 00011 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 00012 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 00013 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 00014 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 * 00016 */ 00017 00018 #ifndef __CIRCULARBUFFER_H_ 00019 #define __CIRCULARBUFFER_H_ 00020 00021 // Unidades usadas do apache. 00022 #include <httpd.h> 00023 00024 // Unidades usadas do sistema. 00025 #include <pthread.h> 00026 00027 // Define a classe usada para implementar um Buffer Circular um um certo numero 00028 // de elementos, sendo que cada elemento armazena um certo numero fixo de bytes 00029 // (no nosso caso, um bloco do RIO). 00030 00031 class CircularBuffer 00032 { 00033 private: 00034 // Armazena o ponteiro para o servidor (somente para poder gerarmos logs 00035 // no log do apache. 00036 server_rec *m_Server; 00037 // Valor booleano usado para indicar se algum erro ocorreu ao 00038 // executarmos o construtor da classe. 00039 bool m_Initialized; 00040 // Variavel booleana para indicar as threads, travadas nas variaveis de 00041 // condicao esperando por um elemento do buffer, nao devem continuar a 00042 // executar a funcao (usada pela funcao limpeza do buffer). 00043 bool m_CancelGetOperation; 00044 // Variavel booleana para indicar as threads, travadas nas variaveis de 00045 // condicao esperando pelo buffer deixar de ficar cheio, nao devem 00046 // continuar a executar a funcao (usada pela funcao de limpeza do 00047 // buffer). 00048 bool m_CancelSetOperation; 00049 // Erro gerado pelas funcoes da biblioteca do sistema. Este erro e 00050 // usado para verificarmos se a classe foi corretamente criada. 00051 int m_SystemStatus; 00052 // Armazena o numero de elementos do buffer. 00053 int m_BufferSize; 00054 // Armazena o tamanho (em bytes) de cada uma dos elementos do buffer. 00055 int m_ElementSize; 00056 // Armazena o indice do proximo elemento a ser retornado. 00057 int m_NextElement; 00058 // Armazena o numero de elementos atualmente no buffer. 00059 int m_TotalElements; 00060 // Ponteiro para o buffer. 00061 char **m_Buffer; 00062 // Mutex para garantir o acesso exclusivo ao buffer. 00063 pthread_mutex_t m_Mutex; 00064 // Variavel de condicao usada para bloquear a thread que requisitar uma 00065 // posicao livre do buffer quando o buffer estiver cheio. 00066 pthread_cond_t m_CondFull; 00067 // Variavel de condicao usada para bloquear a thread que requisitar a 00068 // proxima posicao do buffer com um elemento quando o buffer estiver 00069 // vazio. 00070 pthread_cond_t m_CondEmpty; 00071 00072 public: 00073 /** 00074 * Construtor da classe, usado para criar o objeto. 00075 * @param Server ponteiro para a estrutura com as informacoes do 00076 * servidor (atualmente somente a usamos para imprimir depuracoes). 00077 * @param BufferSize numero de elementos do buffer. 00078 * @param ElementSize tamanho em bytes de cada elemento. 00079 */ 00080 CircularBuffer( server_rec *Server, unsigned int BufferSize, 00081 unsigned int ElementSize ); 00082 /* 00083 * Destrutor da classe, usado para remover um objeto criado. 00084 */ 00085 ~CircularBuffer(); 00086 /* 00087 * Funcao para retornar um ponteiro para o proximo elemento livre do 00088 * buffer. Se o buffer estiver vazio, a funcao bloqueiara a thread que a 00089 * chamou ate que a funcao SetElement seja chamada para usar uma das 00090 * entradas do buffer. 00091 * @param Data ponteiro para o buffer em que copiaremos o conteudo da 00092 * proxima posicao livre do buffer. Este buffer deve ter espaco 00093 * suficiente para armazenar m_ElementSize bytes. 00094 * @return true se a operacao foi executada com sucesso ou false caso 00095 * algum erro tenha ocorrido. 00096 */ 00097 bool GetElement( char *Data ); 00098 /** 00099 * Funcao para retornar o numero de elementos no buffer circular (usada 00100 * pelo novo comando upload, para evitar bloquear quando nao existem 00101 * mais blocos a serem recebidos). 00102 * @param TotalElements ponteiro para um valor inteiro, que sera mudado 00103 * para o numero de blocks no buffer circular. 00104 * @return true se existem elementos no buffer circular e false em caso 00105 * contrario. 00106 */ 00107 bool TotalElements( unsigned int *TotalElements ); 00108 /* Funcao para alterar o proximo elemento livre do buffer. A funcao 00109 * copiara todo o conteudo de Data para este buffer, supondo que o 00110 * numero de bytes de data e igual a m_ElementSize. Se o buffer estiver 00111 * cheio, a funcao bloqueara a thread que a chamou ate que a funcao 00112 * GetElement acima seja chamada. 00113 * @param Data ponteiro para o buffer do qual copiaremos os dados para 00114 * a proxima posicao livre do buffer. 00115 * @return true se a operacao foi executada com sucesso ou false caso 00116 * algum erro tenha ocorrido. 00117 */ 00118 bool SetElement( char *Data ); 00119 /* 00120 * Funcao para esvaziar o buffer, fazendo com que o seu conteudo 00121 * anterior seja desconsiderado (os dados nao sao apagados, somente as 00122 * variaveis do buffer sao definidas para os seus valores iniciais). 00123 * @return true se o buffer foi esvaziado com sucesso ou false se 00124 * algum erro ocorreu. 00125 */ 00126 bool CleanBuffer(); 00127 00128 /** 00129 * Funcao para inicializar as variaveis do buffer. Ela e usada quando 00130 * o buffer e usado mais de uma vez. 00131 */ 00132 bool ReinitializeBuffer(); 00133 00134 /* 00135 * Funcao para desbloquear, com erro, uma thread que esteja bloqueada 00136 * na funcao GetElement. 00137 * @return true se a operacao foi executada com sucesso ou false caso 00138 * algum erro tenha ocorrido. 00139 */ 00140 bool CancelGetElement(); 00141 /* 00142 * Funcao para retornar o erro, caso tenha ocorrido, ao construir o 00143 * objeto da classe. 00144 * @return codigo do erro, que sera diferente de 0 caso alguma das 00145 * funcoes acima retorne false. 00146 */ 00147 int GetError(); 00148 }; 00149 00150 #endif /*__CIRCULARBUFFER_H_*/ 00151