Logo Search packages:      
Sourcecode: pwlib version File versions  Download package

BOOL PQueueChannel::Write ( const void *  buf,
PINDEX  len 
) [virtual]

Low level write to the file channel. The write timeout is ignored for file I/O. The GetLastWriteCount() function returns the actual number of bytes written.

The GetErrorCode() function should be consulted after Write() returns FALSE to determine what caused the failure.

Returns:
TRUE if at least len bytes were written to the channel.
Parameters:
bufPointer to a block of memory to write.
lenNumber of bytes to write.

Reimplemented from PChannel.

Definition at line 209 of file qchannel.cxx.

References PChannel::Interrupted, PChannel::IsOpen(), PChannel::lastWriteCount, PChannel::LastWriteError, PChannel::SetErrorValues(), PSemaphore::Signal(), PSync::Signal(), PChannel::Timeout, PSemaphore::Wait(), PSync::Wait(), and PChannel::writeTimeout.

{
  mutex.Wait();

  lastWriteCount = 0;

  if (!IsOpen()) {
    mutex.Signal();
    return FALSE;
  }

  const BYTE * buffer = (BYTE *)buf;

  /* If queue is full then we should block for the time specifed in the
      write timeout.
    */
  while (queueLength == queueSize) {
    mutex.Signal();

    PTRACE_IF(6, writeTimeout > 0, "QChan\tBlocking on full queue");
    if (!unfull.Wait(writeTimeout)) {
      PTRACE(6, "QChan\tWrite timeout on full queue");
      return SetErrorValues(Timeout, EAGAIN, LastWriteError);
    }

    mutex.Wait();

    if (!IsOpen()) {
      mutex.Signal();
      return SetErrorValues(Interrupted, EINTR, LastWriteError);
    }
  }

  // Calculate number of bytes to copy
  PINDEX copyLen = count;

  // First don't copy more than are availble in queue
  PINDEX bytesLeftInQueue = queueSize - queueLength;
  if (copyLen > bytesLeftInQueue)
    copyLen = bytesLeftInQueue;

  // Then to make things simpler, limit to amount left till the end of the
  // linear part of memory. Another loop around will get rest of data to queue
  PINDEX bytesLeftInUnwrapped = queueSize - enqueuePos;
  if (copyLen > bytesLeftInUnwrapped)
    copyLen = bytesLeftInUnwrapped;

  PAssert(copyLen > 0, "attempt to write zero bytes");

  // Move the data in and increment pointer, decrement bytes yet to queue
  memcpy(queueBuffer + enqueuePos, buffer, copyLen);
  lastWriteCount += copyLen;
  buffer += copyLen;
  count -= copyLen;

  // Move the queue pointer along, wrapping to beginning
  enqueuePos += copyLen;
  if (enqueuePos >= queueSize)
    enqueuePos = 0;

  // see if we need to signal reader that queue was empty
  BOOL queueWasEmpty = queueLength == 0;

  // increment queue length by the amount we copied
  queueLength += copyLen;

  // signal reader if necessary
  if (queueWasEmpty) {
    PTRACE(6, "QChan\tSignalling queue no longer empty");
    unempty.Signal();
  }

  mutex.Signal();

  return TRUE;
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index