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.

TRUE if at least len bytes were written to the channel.
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.


  lastWriteCount = 0;

  if (!IsOpen()) {
    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) {

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


    if (!IsOpen()) {
      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");


  return TRUE;

Here is the call graph for this function:

Generated by  Doxygen 1.6.0   Back to index