#include <CircularBuffer.h>
Public Member Functions | |
CircularBuffer (server_rec *Server, unsigned int BufferSize, unsigned int ElementSize) | |
Construtor da classe, usado para criar o objeto. | |
~CircularBuffer () | |
bool | GetElement (char *Data) |
bool | TotalElements (unsigned int *TotalElements) |
Funcao para retornar o numero de elementos no buffer circular (usada pelo novo comando upload, para evitar bloquear quando nao existem mais blocos a serem recebidos). | |
bool | SetElement (char *Data) |
bool | CleanBuffer () |
bool | ReinitializeBuffer () |
Funcao para inicializar as variaveis do buffer. | |
bool | CancelGetElement () |
int | GetError () |
Private Attributes | |
server_rec * | m_Server |
bool | m_Initialized |
bool | m_CancelGetOperation |
bool | m_CancelSetOperation |
int | m_SystemStatus |
int | m_BufferSize |
int | m_ElementSize |
int | m_NextElement |
int | m_TotalElements |
char ** | m_Buffer |
pthread_mutex_t | m_Mutex |
pthread_cond_t | m_CondFull |
pthread_cond_t | m_CondEmpty |
Definition at line 31 of file CircularBuffer.h.
CircularBuffer::CircularBuffer | ( | server_rec * | Server, | |
unsigned int | BufferSize, | |||
unsigned int | ElementSize | |||
) |
Construtor da classe, usado para criar o objeto.
Server | ponteiro para a estrutura com as informacoes do servidor (atualmente somente a usamos para imprimir depuracoes). | |
BufferSize | numero de elementos do buffer. | |
ElementSize | tamanho em bytes de cada elemento. |
Definition at line 30 of file CircularBuffer.cpp.
00032 { 00033 int i, j; 00034 int status; 00035 00036 // Inicializa as variaveis da classe 00037 m_Server = Server; 00038 m_BufferSize = BufferSize; 00039 m_ElementSize = ElementSize; 00040 m_SystemStatus = 0; 00041 m_NextElement = 0; 00042 m_TotalElements = 0; 00043 m_Initialized = false; 00044 m_CancelGetOperation = false; 00045 m_CancelSetOperation = false; 00046 00047 // Aloca o buffer de acordo com o tamanho passado, com cada elemento tendo 00048 // ElementSize bytes. 00049 00050 m_Buffer = new char*[ m_BufferSize ]; 00051 if( m_Buffer == NULL ) 00052 { 00053 m_SystemStatus = ENOMEM; 00054 00055 #ifdef RIO_DEBUG2 00056 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00057 "Error allocation m_Buffer: %u (%s)", m_SystemStatus, 00058 strerror( m_SystemStatus ) ); 00059 #endif 00060 00061 return; 00062 } 00063 00064 for( i = 0; i < m_BufferSize; i++ ) 00065 { 00066 m_Buffer[ i ] = new char[ m_ElementSize ]; 00067 if( m_Buffer[ i ] == NULL ) 00068 { 00069 00070 m_SystemStatus = ENOMEM; 00071 00072 #ifdef RIO_DEBUG2 00073 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00074 "Error allocation m_Buffer: %u (%s)", m_SystemStatus, 00075 strerror( m_SystemStatus ) ); 00076 #endif 00077 00078 // Remove o que ja foi alocado 00079 for( j = 0; j < i; j++ ) 00080 delete[] m_Buffer[ j ]; 00081 00082 delete[] m_Buffer; 00083 00084 m_Buffer = NULL; 00085 return; 00086 } 00087 } 00088 00089 // Inicializa os mutexes usados pela classe e a variavel de condicao usada 00090 // pela classe. 00091 status = pthread_mutex_init( &m_Mutex, NULL ); 00092 if( status < 0 ) 00093 { 00094 m_SystemStatus = status; 00095 00096 #ifdef RIO_DEBUG2 00097 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00098 "Error initializing m_Mutex: %u (%s)", m_SystemStatus, 00099 strerror( m_SystemStatus ) ); 00100 #endif 00101 00102 return; 00103 } 00104 00105 status = pthread_cond_init( &m_CondFull, NULL ); 00106 if( status < 0 ) 00107 { 00108 m_SystemStatus = status; 00109 00110 #ifdef RIO_DEBUG2 00111 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00112 "Error initializing m_CondFull: %u (%s)", m_SystemStatus, 00113 strerror( m_SystemStatus ) ); 00114 #endif 00115 00116 return; 00117 } 00118 00119 status = pthread_cond_init( &m_CondEmpty, NULL ); 00120 if( status < 0 ) 00121 { 00122 m_SystemStatus = status; 00123 00124 #ifdef RIO_DEBUG2 00125 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00126 "Error initializing m_CondEmpty: %u (%s)", m_SystemStatus, 00127 strerror( m_SystemStatus ) ); 00128 #endif 00129 00130 return; 00131 } 00132 00133 m_Initialized = true; 00134 }
CircularBuffer::~CircularBuffer | ( | ) |
Definition at line 137 of file CircularBuffer.cpp.
00138 { 00139 int i; 00140 int status; 00141 00142 // Limpa o buffer (desbloqueando threads que podem estar bloqueadas). 00143 CleanBuffer(); 00144 00145 // Remove o buffer 00146 if( m_Buffer != NULL ) 00147 { 00148 // Remove o que ja foi alocado 00149 for( i = 0; i < m_BufferSize; i++ ) 00150 delete[] m_Buffer[ i ]; 00151 00152 delete[] m_Buffer; 00153 00154 m_Buffer = NULL; 00155 } 00156 00157 // Remove os mutexes e variaveis de condicao. 00158 status = pthread_mutex_destroy( &m_Mutex ); 00159 if( status < 0 ) 00160 { 00161 #ifdef RIO_DEBUG2 00162 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00163 "Error destroying m_Mutex: %u (%s)", status, 00164 strerror( status ) ); 00165 #endif 00166 } 00167 00168 status = pthread_cond_destroy( &m_CondFull ); 00169 if( status < 0 ) 00170 { 00171 #ifdef RIO_DEBUG2 00172 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00173 "Error destroying m_CondFull: %u (%s)", status, 00174 strerror( status ) ); 00175 #endif 00176 } 00177 00178 status = pthread_cond_destroy( &m_CondEmpty ); 00179 if( status < 0 ) 00180 { 00181 #ifdef RIO_DEBUG2 00182 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00183 "Error destroying m_CondEmpty: %u (%s)", status, 00184 strerror( status ) ); 00185 #endif 00186 } 00187 }
bool CircularBuffer::CancelGetElement | ( | ) |
Definition at line 755 of file CircularBuffer.cpp.
00756 { 00757 int status; 00758 bool Result; 00759 00760 #ifdef RIO_DEBUG2 00761 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00762 "Executing CancelGetElement" ); 00763 #endif 00764 00765 // Inicializa o retorno da funcao. 00766 Result = true; 00767 00768 if( !m_Initialized ) 00769 { 00770 00771 #ifdef RIO_DEBUG2 00772 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00773 "Circular buffer not initialized" ); 00774 #endif 00775 00776 return false; 00777 } 00778 00779 // Obtem o acesso exclusivo ao buffer. 00780 status = pthread_mutex_lock( &m_Mutex ); 00781 if( status < 0 ) 00782 { 00783 m_SystemStatus = status; 00784 00785 #ifdef RIO_DEBUG2 00786 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00787 "Error locking m_Mutex: %u (%s)", m_SystemStatus, 00788 strerror( m_SystemStatus ) ); 00789 #endif 00790 00791 return false; 00792 } 00793 00794 // Cancela a espera pelo buffer ter algum elemento. 00795 // Cancela a thread pendente em GetElement. 00796 m_CancelGetOperation = true; 00797 00798 status = pthread_cond_signal( &m_CondEmpty ); 00799 if( status < 0 ) 00800 { 00801 m_SystemStatus = status; 00802 00803 #ifdef RIO_DEBUG2 00804 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00805 "Error signalling m_CondEmpty: %u (%s)", 00806 m_SystemStatus, strerror( m_SystemStatus ) ); 00807 #endif 00808 00809 Result = false; 00810 } 00811 00812 // Libera o acesso exclusivo ao buffer. 00813 status = pthread_mutex_unlock( &m_Mutex ); 00814 if( status < 0 ) 00815 { 00816 m_SystemStatus = status; 00817 00818 #ifdef RIO_DEBUG2 00819 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00820 "Error unlocking m_Mutex: %u (%s)", m_SystemStatus, 00821 strerror( m_SystemStatus ) ); 00822 #endif 00823 00824 return false; 00825 } 00826 00827 return( Result ); 00828 }
bool CircularBuffer::CleanBuffer | ( | ) |
Definition at line 618 of file CircularBuffer.cpp.
00619 { 00620 int status; 00621 00622 #ifdef RIO_DEBUG2 00623 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Executing CleanBuffer" ); 00624 #endif 00625 00626 if( !m_Initialized ) 00627 { 00628 00629 #ifdef RIO_DEBUG2 00630 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00631 "Circular buffer not initialized (3)" ); 00632 #endif 00633 00634 return false; 00635 } 00636 00637 // Obtem o acesso exclusivo ao buffer. 00638 status = pthread_mutex_lock( &m_Mutex ); 00639 if( status < 0 ) 00640 { 00641 m_SystemStatus = status; 00642 00643 #ifdef RIO_DEBUG2 00644 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00645 "Error locking m_Mutex: %u (%s)", m_SystemStatus, 00646 strerror( m_SystemStatus ) ); 00647 #endif 00648 00649 return false; 00650 } 00651 00652 // Cancela a espera pelo buffer deixar de ficar cheio, se isso for 00653 // necessario (ou seja, se m_TotalElementsfor igual a m_BufferSize). 00654 if( m_TotalElements == m_BufferSize ) 00655 { 00656 // Indica a thread que a espera foi cancelada, ou que ela nao precisa 00657 // mais esperar. 00658 m_CancelSetOperation = true; 00659 00660 status = pthread_cond_signal( &m_CondFull ); 00661 if( status < 0 ) 00662 { 00663 m_SystemStatus = status; 00664 00665 #ifdef RIO_DEBUG2 00666 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00667 "Error signalling m_CondFull: %u (%s)", 00668 m_SystemStatus, strerror( m_SystemStatus ) ); 00669 #endif 00670 00671 // Libera o acesso exclusivo ao buffer. 00672 status = pthread_mutex_unlock( &m_Mutex ); 00673 if( status < 0 ) 00674 { 00675 m_SystemStatus = status; 00676 00677 #ifdef RIO_DEBUG2 00678 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00679 "Error unlocking m_Mutex: %u (%s)", 00680 m_SystemStatus, strerror( m_SystemStatus ) ); 00681 #endif 00682 00683 return false; 00684 } 00685 00686 return false; 00687 } 00688 } 00689 00690 // Cancela a espera pelo buffer ter algum elemento, se isso for necessario 00691 // (ou seja, se m_TotalElementsfor igual a 0). 00692 if( m_TotalElements == 0 ) 00693 { 00694 // Indica a thread que a espera foi cancelada, ou que ela nao precisa 00695 // mais esperar. 00696 m_CancelGetOperation = true; 00697 00698 status = pthread_cond_signal( &m_CondEmpty ); 00699 if( status < 0 ) 00700 { 00701 m_SystemStatus = status; 00702 00703 #ifdef RIO_DEBUG2 00704 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00705 "Error signalling m_CondEmpty: %u (%s)", 00706 m_SystemStatus, strerror( m_SystemStatus ) ); 00707 #endif 00708 00709 // Libera o acesso exclusivo ao buffer. 00710 status = pthread_mutex_unlock( &m_Mutex ); 00711 if( status < 0 ) 00712 { 00713 m_SystemStatus = status; 00714 00715 #ifdef RIO_DEBUG2 00716 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00717 "Error unlocking m_Mutex: %u (%s)", 00718 m_SystemStatus, strerror( m_SystemStatus ) ); 00719 #endif 00720 00721 return false; 00722 } 00723 00724 return false; 00725 } 00726 } 00727 00728 // Limpa as variaveis do buffer. 00729 m_TotalElements = 0; 00730 m_NextElement = 0; 00731 00732 // Libera o acesso exclusivo ao buffer. 00733 status = pthread_mutex_unlock( &m_Mutex ); 00734 if( status < 0 ) 00735 { 00736 m_SystemStatus = status; 00737 00738 #ifdef RIO_DEBUG2 00739 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00740 "Error unlocking m_Mutex: %u (%s)", m_SystemStatus, 00741 strerror( m_SystemStatus ) ); 00742 #endif 00743 00744 return false; 00745 } 00746 00747 // Limpa o codigo de erro. 00748 m_SystemStatus = 0; 00749 00750 return true; 00751 }
bool CircularBuffer::GetElement | ( | char * | Data | ) |
Definition at line 190 of file CircularBuffer.cpp.
00191 { 00192 int status; 00193 00194 // Verifica se a classe foi inicializada. 00195 if( !m_Initialized ) 00196 { 00197 00198 #ifdef RIO_DEBUG2 00199 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00200 "Circular buffer not initialized (1)" ); 00201 #endif 00202 00203 return false; 00204 } 00205 00206 #ifdef RIO_DEBUG2 00207 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00208 "Trying to remove a element in buffer" ); 00209 #endif 00210 00211 // Obtem o acesso exclusivo ao buffer. 00212 status = pthread_mutex_lock( &m_Mutex ); 00213 if( status < 0 ) 00214 { 00215 m_SystemStatus = status; 00216 00217 #ifdef RIO_DEBUG2 00218 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00219 "Error locking m_Mutex: %u (%s)", m_SystemStatus, 00220 strerror( m_SystemStatus ) ); 00221 #endif 00222 00223 return false; 00224 } 00225 00226 // Verifica se o buffer esta vazio e, caso esteja, bloqueia a thread que 00227 // chamou a funcao ate que SetElement seja chamada. 00228 if( m_TotalElements == 0 ) 00229 { 00230 #ifdef RIO_DEBUG2 00231 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00232 "Buffer is empty. Waiting for a element" ); 00233 #endif 00234 00235 if( !m_CancelGetOperation ) 00236 { 00237 status = pthread_cond_wait( &m_CondEmpty, &m_Mutex ); 00238 if( status < 0 ) 00239 { 00240 m_SystemStatus = status; 00241 00242 #ifdef RIO_DEBUG2 00243 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00244 "Error waiting in m_CondEmpty: %u (%s)", 00245 m_SystemStatus, strerror( m_SystemStatus ) ); 00246 #endif 00247 00248 status = pthread_mutex_unlock( &m_Mutex ); 00249 if( status < 0 ) 00250 { 00251 m_SystemStatus = status; 00252 00253 #ifdef RIO_DEBUG2 00254 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00255 "Error unlocking m_Mutex: %u (%s)", 00256 m_SystemStatus, strerror( m_SystemStatus ) ); 00257 #endif 00258 00259 return false; 00260 } 00261 00262 return false; 00263 } 00264 } 00265 00266 // Verifica se o numero de elementos e 0. Se isso ocorreu, a operacao 00267 // foi cancelada sem colocarmos elementos no buffer, e deveremos 00268 // Inicializamos a variavel de cancelamento para false, pois ja passamos 00269 // pela variavel de condicao. 00270 m_CancelGetOperation = false; 00271 00272 // retornar um codigo de erro neste caso. 00273 if( m_TotalElements == 0 ) 00274 { 00275 #ifdef RIO_DEBUG2 00276 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00277 "GetElement Operation was cancelled" ); 00278 #endif 00279 00280 status = pthread_mutex_unlock( &m_Mutex ); 00281 if( status < 0 ) 00282 { 00283 m_SystemStatus = status; 00284 00285 #ifdef RIO_DEBUG2 00286 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00287 "Error unlocking m_Mutex: %u (%s)", 00288 m_SystemStatus, strerror( m_SystemStatus ) ); 00289 #endif 00290 00291 return false; 00292 } 00293 00294 return false; 00295 } 00296 } 00297 00298 #ifdef RIO_DEBUG2 00299 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00300 "Removing element with %u bytes of %u (%u/%u elements)", 00301 m_ElementSize, m_NextElement, m_TotalElements, m_BufferSize ); 00302 #endif 00303 00304 // Copia os dados do elemento atual para Data. 00305 memcpy( Data, m_Buffer[ m_NextElement ], m_ElementSize ); 00306 00307 // Atualiza o ponteiro para o proximo elemento. 00308 m_NextElement = ( m_NextElement + 1 ) % m_BufferSize; 00309 00310 // Decrementa o contador com o numero de elementos disponiveis 00311 m_TotalElements--; 00312 00313 // Verifica se precisamos enviar um sinal para a variavel de condicao 00314 // m_CondFull, caso o numero de elementos fosse igual a m_BufferSize, pois 00315 // alguma thread pode, neste caso, estar bloqueada em SetElement. 00316 if( m_TotalElements == ( m_BufferSize - 1 ) ) 00317 { 00318 #ifdef RIO_DEBUG2 00319 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00320 "Buffer was full. Sending a signal to m_CondFull" ); 00321 #endif 00322 00323 status = pthread_cond_signal( &m_CondFull ); 00324 if( status < 0 ) 00325 { 00326 m_SystemStatus = status; 00327 00328 #ifdef RIO_DEBUG2 00329 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00330 "Error signalling m_CondFull: %u (%s)", 00331 m_SystemStatus, strerror( m_SystemStatus ) ); 00332 #endif 00333 00334 status = pthread_mutex_unlock( &m_Mutex ); 00335 if( status < 0 ) 00336 { 00337 m_SystemStatus = status; 00338 00339 #ifdef RIO_DEBUG2 00340 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00341 "Error unlocking m_Mutex: %u (%s)", 00342 m_SystemStatus, strerror( m_SystemStatus ) ); 00343 #endif 00344 00345 return false; 00346 } 00347 00348 return false; 00349 } 00350 } 00351 00352 // Libera o acesso exclusivo ao buffer. 00353 status = pthread_mutex_unlock( &m_Mutex ) ; 00354 if( status < 0 ) 00355 { 00356 m_SystemStatus = status; 00357 00358 #ifdef RIO_DEBUG2 00359 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00360 "Error unlocking m_Mutex: %u (%s)", m_SystemStatus, 00361 strerror( m_SystemStatus ) ); 00362 #endif 00363 00364 return false; 00365 } 00366 00367 return true; 00368 }
int CircularBuffer::GetError | ( | ) |
Definition at line 893 of file CircularBuffer.cpp.
00894 { 00895 return m_SystemStatus; 00896 }
bool CircularBuffer::ReinitializeBuffer | ( | ) |
Funcao para inicializar as variaveis do buffer.
Ela e usada quando o buffer e usado mais de uma vez.
Definition at line 832 of file CircularBuffer.cpp.
00833 { 00834 int status; 00835 00836 #ifdef RIO_DEBUG2 00837 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00838 "Executing ReinitializeBuffer" ); 00839 #endif 00840 00841 if( !m_Initialized ) 00842 { 00843 00844 #ifdef RIO_DEBUG2 00845 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00846 "Circular buffer not initialized" ); 00847 #endif 00848 00849 return false; 00850 } 00851 00852 // Obtem o acesso exclusivo ao buffer. 00853 status = pthread_mutex_lock( &m_Mutex ); 00854 if( status < 0 ) 00855 { 00856 m_SystemStatus = status; 00857 00858 #ifdef RIO_DEBUG2 00859 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00860 "Error locking m_Mutex: %u (%s)", m_SystemStatus, 00861 strerror( m_SystemStatus ) ); 00862 #endif 00863 00864 return false; 00865 } 00866 00867 m_SystemStatus = 0; 00868 m_NextElement = 0; 00869 m_TotalElements = 0; 00870 m_CancelGetOperation = false; 00871 m_CancelSetOperation = false; 00872 00873 // Libera o acesso exclusivo ao buffer. 00874 status = pthread_mutex_unlock( &m_Mutex ); 00875 if( status < 0 ) 00876 { 00877 m_SystemStatus = status; 00878 00879 #ifdef RIO_DEBUG2 00880 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00881 "Error unlocking m_Mutex: %u (%s)", m_SystemStatus, 00882 strerror( m_SystemStatus ) ); 00883 #endif 00884 00885 return false; 00886 } 00887 00888 return true; 00889 }
bool CircularBuffer::SetElement | ( | char * | Data | ) |
Definition at line 435 of file CircularBuffer.cpp.
00436 { 00437 unsigned int FreeElement; 00438 int status; 00439 00440 if( !m_Initialized ) 00441 { 00442 00443 #ifdef RIO_DEBUG2 00444 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00445 "Circular buffer not initialized (2)" ); 00446 #endif 00447 00448 return false; 00449 } 00450 00451 #ifdef RIO_DEBUG2 00452 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00453 "Trying to insert a element in buffer" ); 00454 #endif 00455 00456 status = pthread_mutex_lock( &m_Mutex ); 00457 // Obtem o acesso exclusivo ao buffer. 00458 if( status < 0 ) 00459 { 00460 m_SystemStatus = status; 00461 00462 #ifdef RIO_DEBUG2 00463 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00464 "Error locking m_Mutex: %u (%s)", m_SystemStatus, 00465 strerror( m_SystemStatus ) ); 00466 #endif 00467 00468 return false; 00469 } 00470 00471 // Verifica se o buffer esta chei e, caso esteja, bloqueia a thread que 00472 // chamou a funcao ate que GetElement seja chamada. 00473 if( m_TotalElements == m_BufferSize ) 00474 { 00475 #ifdef RIO_DEBUG2 00476 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00477 "Buffer is full. Waiting for a empty buffer entry" ); 00478 #endif 00479 00480 if( !m_CancelSetOperation ) 00481 { 00482 status = pthread_cond_wait( &m_CondFull, &m_Mutex ); 00483 if( status < 0 ) 00484 { 00485 m_SystemStatus = status; 00486 00487 #ifdef RIO_DEBUG2 00488 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00489 "Error waiting in m_CondFull: %u (%s)", 00490 m_SystemStatus, strerror( m_SystemStatus ) ); 00491 #endif 00492 00493 status = pthread_mutex_unlock( &m_Mutex ); 00494 if( status < 0 ) 00495 { 00496 m_SystemStatus = status; 00497 00498 #ifdef RIO_DEBUG2 00499 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00500 "Error unlocking m_Mutex: %u (%s)", 00501 m_SystemStatus, strerror( m_SystemStatus ) ); 00502 #endif 00503 00504 return false; 00505 } 00506 00507 return false; 00508 } 00509 } 00510 00511 // Verifica se o buffer esta cheio. Se isso ocorreu, a operacao foi 00512 // cancelada sem removermos elementos no buffer. Inicializamos a 00513 // variavel de cancelamento para false, pois ja passamos pela variavel 00514 // de condicao. 00515 m_CancelSetOperation = false; 00516 00517 // Verifica se a operacao foi cancelada 00518 if( m_TotalElements == m_BufferSize ) 00519 { 00520 #ifdef RIO_DEBUG2 00521 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00522 "SetElement Operation was cancelled" ); 00523 #endif 00524 00525 status = pthread_mutex_unlock( &m_Mutex ); 00526 if( status < 0 ) 00527 { 00528 m_SystemStatus = status; 00529 00530 #ifdef RIO_DEBUG2 00531 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00532 "Error unlocking m_Mutex: %u (%s)", 00533 m_SystemStatus, strerror( m_SystemStatus ) ); 00534 #endif 00535 00536 return false; 00537 } 00538 00539 return false; 00540 } 00541 } 00542 00543 // Descobre a proxima entrada livre do buffer (como o buffer e circular, 00544 // esta posicao sera o valor obtido ao aplicarmos o modulo sobre a soma 00545 // m_NextElement + m_TotalElements). 00546 FreeElement = ( m_NextElement + m_TotalElements ) % m_BufferSize; 00547 00548 // Copia os dados do elemento atual para Data. 00549 memcpy( m_Buffer[ FreeElement ], Data, m_ElementSize ); 00550 00551 // Incrementa o contador com o numero de elementos disponiveis 00552 m_TotalElements++; 00553 00554 // Verifica se precisamos enviar um sinal para a variavel de condicao 00555 // m_CondEmpty, caso o buffer estivesse vazio, pois alguma thread pode, 00556 // neste caso, estar bloqueada em GetElement. 00557 if( m_TotalElements == 1 ) 00558 { 00559 #ifdef RIO_DEBUG2 00560 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00561 "Buffer was empty. Sending a signal to m_CondEmpty" ); 00562 #endif 00563 00564 status = pthread_cond_signal( &m_CondEmpty ); 00565 if( status < 0 ) 00566 { 00567 m_SystemStatus = status; 00568 00569 #ifdef RIO_DEBUG2 00570 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00571 "Error signalling m_CondEmpty: %u (%s)", 00572 m_SystemStatus, strerror( m_SystemStatus ) ); 00573 #endif 00574 00575 status = pthread_mutex_unlock( &m_Mutex ); 00576 if( status < 0 ) 00577 { 00578 m_SystemStatus = status; 00579 00580 #ifdef RIO_DEBUG2 00581 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00582 "Error unlocking m_Mutex: %u (%s)", 00583 m_SystemStatus, strerror( m_SystemStatus ) ); 00584 #endif 00585 00586 return false; 00587 } 00588 00589 return false; 00590 } 00591 } 00592 00593 #ifdef RIO_DEBUG2 00594 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00595 "Inserting a element with %u bytes in %u (%u/%u elements)", 00596 m_ElementSize, FreeElement, m_TotalElements, m_BufferSize ); 00597 #endif 00598 00599 // Libera o acesso exclusivo ao buffer. 00600 status = pthread_mutex_unlock( &m_Mutex ); 00601 if( status < 0 ) 00602 { 00603 m_SystemStatus = status; 00604 00605 #ifdef RIO_DEBUG2 00606 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00607 "Error unlocking m_Mutex: %u (%s)", m_SystemStatus, 00608 strerror( m_SystemStatus ) ); 00609 #endif 00610 00611 return false; 00612 } 00613 00614 return true; 00615 }
bool CircularBuffer::TotalElements | ( | unsigned int * | TotalElements | ) |
Funcao para retornar o numero de elementos no buffer circular (usada pelo novo comando upload, para evitar bloquear quando nao existem mais blocos a serem recebidos).
TotalElements | ponteiro para um valor inteiro, que sera mudado para o numero de blocks no buffer circular. |
Definition at line 373 of file CircularBuffer.cpp.
00374 { 00375 int status; 00376 00377 // Inicializa o ponteiro passado para false, caso erros ocorram ao chamar a 00378 // funcao. 00379 *TotalElements = 0; 00380 00381 // Verifica se a classe foi inicializada. 00382 if( !m_Initialized ) 00383 { 00384 00385 #ifdef RIO_DEBUG2 00386 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00387 "Circular buffer not initialized (4)" ); 00388 #endif 00389 00390 return false; 00391 } 00392 00393 #ifdef RIO_DEBUG2 00394 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00395 "Trying to remove a element in buffer" ); 00396 #endif 00397 00398 // Obtem o acesso exclusivo ao buffer. 00399 status = pthread_mutex_lock( &m_Mutex ); 00400 if( status < 0 ) 00401 { 00402 m_SystemStatus = status; 00403 00404 #ifdef RIO_DEBUG2 00405 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00406 "Error locking m_Mutex: %u (%s)", m_SystemStatus, 00407 strerror( m_SystemStatus ) ); 00408 #endif 00409 00410 return false; 00411 } 00412 00413 // Salva o numero total de elementos. 00414 *TotalElements = m_TotalElements; 00415 00416 // Libera o acesso exclusivo ao buffer. 00417 status = pthread_mutex_unlock( &m_Mutex ) ; 00418 if( status < 0 ) 00419 { 00420 m_SystemStatus = status; 00421 00422 #ifdef RIO_DEBUG2 00423 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, 00424 "Error unlocking m_Mutex: %u (%s)", m_SystemStatus, 00425 strerror( m_SystemStatus ) ); 00426 #endif 00427 00428 return false; 00429 } 00430 00431 return true; 00432 }
char** CircularBuffer::m_Buffer [private] |
Definition at line 61 of file CircularBuffer.h.
int CircularBuffer::m_BufferSize [private] |
Definition at line 53 of file CircularBuffer.h.
bool CircularBuffer::m_CancelGetOperation [private] |
Definition at line 43 of file CircularBuffer.h.
bool CircularBuffer::m_CancelSetOperation [private] |
Definition at line 48 of file CircularBuffer.h.
pthread_cond_t CircularBuffer::m_CondEmpty [private] |
Definition at line 70 of file CircularBuffer.h.
pthread_cond_t CircularBuffer::m_CondFull [private] |
Definition at line 66 of file CircularBuffer.h.
int CircularBuffer::m_ElementSize [private] |
Definition at line 55 of file CircularBuffer.h.
bool CircularBuffer::m_Initialized [private] |
Definition at line 39 of file CircularBuffer.h.
pthread_mutex_t CircularBuffer::m_Mutex [private] |
Definition at line 63 of file CircularBuffer.h.
int CircularBuffer::m_NextElement [private] |
Definition at line 57 of file CircularBuffer.h.
server_rec* CircularBuffer::m_Server [private] |
Definition at line 36 of file CircularBuffer.h.
int CircularBuffer::m_SystemStatus [private] |
Definition at line 51 of file CircularBuffer.h.
int CircularBuffer::m_TotalElements [private] |
Definition at line 59 of file CircularBuffer.h.