CircularBuffer Class Reference

#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

Detailed Description

Definition at line 31 of file CircularBuffer.h.


Constructor & Destructor Documentation

CircularBuffer::CircularBuffer ( server_rec *  Server,
unsigned int  BufferSize,
unsigned int  ElementSize 
)

Construtor da classe, usado para criar o objeto.

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


Member Function Documentation

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

Parameters:
TotalElements ponteiro para um valor inteiro, que sera mudado para o numero de blocks no buffer circular.
Returns:
true se existem elementos no buffer circular e false em caso contrario.

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 }


Field Documentation

char** CircularBuffer::m_Buffer [private]

Definition at line 61 of file CircularBuffer.h.

Definition at line 53 of file CircularBuffer.h.

Definition at line 43 of file CircularBuffer.h.

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.

Definition at line 55 of file CircularBuffer.h.

Definition at line 39 of file CircularBuffer.h.

pthread_mutex_t CircularBuffer::m_Mutex [private]

Definition at line 63 of file CircularBuffer.h.

Definition at line 57 of file CircularBuffer.h.

server_rec* CircularBuffer::m_Server [private]

Definition at line 36 of file CircularBuffer.h.

Definition at line 51 of file CircularBuffer.h.

Definition at line 59 of file CircularBuffer.h.


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