Beispiel #1
0
/** Create a BufferedWriter instance
 *
 * \param outStream opaque OmlOutStream handler
 * \param queueCapacity maximal size [B] of the internal queue queueCapaity/chunkSize will be used (at least 2)
 * \param chunkSize size [B] of buffer space allocated at a time, set to 0 for default (DEF_CHAIN_BUFFER_SIZE)
 * \return an instance pointer if successful, NULL otherwise
 *
 * \see DEF_CHAIN_BUFFER_SIZE
 */
BufferedWriter*
bw_create(OmlOutStream* outStream, long  queueCapacity, long chunkSize)
{
  long nchunks;
  BufferedWriter* self = NULL;

  assert(outStream>=0);
  assert(queueCapacity>=0);
  assert(chunkSize>=0);

  if((self = (BufferedWriter*)oml_malloc(sizeof(BufferedWriter)))) {
    memset(self, 0, sizeof(BufferedWriter));

    self->outStream = outStream;
    /* This forces a 'connected' INFO message upon first connection */
    self->backoff = 1;

    self->bufSize = chunkSize > 0 ? chunkSize : DEF_CHAIN_BUFFER_SIZE;

    nchunks = queueCapacity / self->bufSize;
    self->unallocatedBuffers = (nchunks > 2) ? nchunks : 2; /* at least two chunks */

    logdebug ("%s: Buffer size %dB (%d chunks of %dB)\n",
        self->outStream->dest,
        self->unallocatedBuffers*self->bufSize,
        self->unallocatedBuffers, self->bufSize);

    if(NULL == (self->writerChunk = self->nextReaderChunk = self->firstChunk = createBufferChunk(self))) {
      oml_free(self);
      self = NULL;

    } else if(NULL == (self->meta_buf = mbuf_create())) {
      destroyBufferChain(self);
      oml_free(self);
      self = NULL;

    } else if(NULL == (self->read_buf = mbuf_create())) {
      destroyBufferChain(self);
      oml_free(self);
      self = NULL;

    } else {
      /* Initialize mutex and condition variable objects */
      pthread_cond_init(&self->semaphore, NULL);
      pthread_mutex_init(&self->lock, NULL);
      logdebug3("%s: initialised mutex %p\n", self->outStream->dest, &self->lock);
      pthread_mutex_init(&self->meta_lock, NULL);
      logdebug3("%s: initialised mutex %p\n", self->outStream->dest, &self->meta_lock);

      /* Initialize and set thread detached attribute */
      pthread_attr_t tattr;
      pthread_attr_init(&tattr);
      pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
      self->active = 1;
      pthread_create(&self->readerThread, &tattr, bufferedWriterThread, (void*)self);
    }
  }

  return (BufferedWriter*)self;
}
Beispiel #2
0
/** Close an output stream and destroy the objects.
 *
 * \param instance handle (i.e., pointer) to a BufferedWriter
 */
void
bw_close(BufferedWriter* instance)
{
  int *retval;
  BufferedWriter *self = (BufferedWriter*)instance;

  if(!self) { return; }

  if (oml_lock (&self->lock, __FUNCTION__)) { return; }
  self->active = 0;

  loginfo ("%s: Waiting for buffered queue thread to drain...\n", self->outStream->dest);

  pthread_cond_signal (&self->semaphore);
  oml_unlock (&self->lock, __FUNCTION__);

  if(pthread_join (self->readerThread, (void**)&retval)) {
    logwarn ("%s: Cannot join buffered queue reader thread: %s\n",
        self->outStream->dest, strerror(errno));

  } else {
    if (1 == *retval) {
      logdebug ("%s: Buffered queue fully drained\n", self->outStream->dest);
    } else {
      logerror ("%s: Buffered queue did not fully drain\n",
          self->outStream->dest, *retval);
    }
  }

  self->outStream->close(self->outStream);
  destroyBufferChain(self);
  oml_free(self);
}
Beispiel #3
0
/** Close an output stream and destroy the objects.
 *
 * \param instance handle (i.e., pointer) to a BufferedWriter
 */
void bw_close(BufferedWriterHdl instance) {
  BufferedWriter *next, *self = (BufferedWriter*)instance;

  if(!self)
    return;

  if (oml_lock (&self->lock, "bw_close")) return;
  self->active = 0;

  loginfo ("Waiting for buffered queue reader thread to drain...\n");

  pthread_cond_signal (&self->semaphore);
  oml_unlock (&self->lock, "bw_close");
  //  pthread_cond_destroy(&self->semaphore, NULL);
  switch (pthread_join (self->readerThread, NULL)) {
  case 0:
    loginfo ("Buffered queue reader thread finished OK...\n");
    break;
  case EINVAL:
    logerror ("Buffered queue reader thread is not joinable\n");
    break;
  case EDEADLK:
    logerror ("Buffered queue reader thread shutdown deadlock, or self-join\n");
    break;
  case ESRCH:
    logerror ("Buffered queue reader thread shutdown failed: could not find the thread\n");
    break;
  default:
    logerror ("Buffered queue reader thread shutdown failed with an unknown error\n");
    break;
  }

  destroyBufferChain(self);
  xfree(self);
}