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

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

Low level read from the file channel. The read timeout is ignored for file I/O. The GetLastReadCount() function returns the actual number of bytes read.

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

TRUE indicates that at least one character was read from the channel. FALSE means no bytes were read due to timeout or some other I/O error.
bufPointer to a block of memory to receive the read bytes.
lenMaximum number of bytes to read into the buffer.

Reimplemented from PChannel.

Definition at line 125 of file qchannel.cxx.

References PChannel::Interrupted, PChannel::IsOpen(), PChannel::lastReadCount, PChannel::LastReadError, PChannel::readTimeout, PChannel::SetErrorValues(), PSemaphore::Signal(), PSync::Signal(), PChannel::Timeout, PSemaphore::Wait(), and PSync::Wait().

Referenced by Test5Thread::Main().


  lastReadCount = 0;

  if (!IsOpen()) {
    return FALSE;

  BYTE * buffer = (BYTE *)buf;

  /* If queue is empty then we should block for the time specifed in the
      read timeout.
  while (queueLength == 0) {

    // unlock the data

    // block until data has arrived
    PTRACE_IF(6, readTimeout > 0, "QChan\tBlocking on empty queue");
    if (!unempty.Wait(readTimeout)) {
      PTRACE(6, "QChan\tRead timeout on empty queue");
      return SetErrorValues(Timeout, EAGAIN, LastReadError);

    // relock the data

    // check if the channel is still open
    if (!IsOpen()) {
      return SetErrorValues(Interrupted, EINTR, LastReadError);

  // should always have data now
  PAssert(queueLength > 0, "read queue signalled without data");

  // To make things simpler, limit to amount to copy out of queue to till
  // the end of the linear part of memory. Another loop around will get
  // rest of data to dequeue
  PINDEX copyLen = queueSize - dequeuePos;

  // But do not copy more than has actually been queued
  if (copyLen > queueLength)
    copyLen = queueLength;

  // Or more than has been requested
  if (copyLen > count)
    copyLen = count;

  PAssert(copyLen > 0, "zero copy length");

  // Copy data out and increment pointer, decrement bytes yet to dequeue
  memcpy(buffer, queueBuffer+dequeuePos, copyLen);
  lastReadCount += copyLen;
  buffer += copyLen;
  count -= copyLen;

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

  // If buffer was full, signal possibly blocked write of data to queue
  // that it can write to queue now.
  if (queueLength == queueSize) {
    PTRACE(6, "QChan\tSignalling queue no longer full");

  // Now decrement queue length by the amount we copied
  queueLength -= copyLen;

  // unlock the buffer

  return TRUE;

Here is the call graph for this function:

Here is the caller graph for this function:

Generated by  Doxygen 1.6.0   Back to index