int bufRead(struct ThreadedCircularBuf* buf, SymbolType* data) { int res; res = 1; //sem_wait(buf->fillCnt); //pthread_mutex_lock(&(buf->m)); /* Critical Section */ //if (buf->cnt > 0) //Should never be empty if (buf->start != buf->end) { memcpy(data, buf->content + (buf->start)*(buf->len), buf->len); buf->start = (buf->start + 1) % buf->N; //printf("read:%d\n", buf->rcount++); //buf->cnt--; } else { //printf("Warning: empty buffer!\n"); //buf->empty = 1; pthread_cond_wait(&(buf->c), &(buf->m)); return bufRead(buf,data); res = 0; } /* End of critical section */ //pthread_mutex_unlock(&(buf->m)); //sem_post(buf->emptyCnt); return res; }
int main(int argc, char *argv[]) { const int numWrites = 4, numReads = 10, numBufs = 3, maxN = 20; int i,j; data_t datum; bool_t shouldReset; bool_t datumOut; buf_t **bufs = (buf_t **)malloc(numBufs * sizeof(buf_t *)); for (i=0; i<numBufs; i++) bufs[i] = bufAlloc(maxN); for (i=0; i<numWrites; i++) { for (j=0; j<numBufs; j++) bufWrite(bufs[j], randomIdx(bufs[j]), (data_t)__VERIFIER_nondet_int()); } for (i=0; i<numReads; i++) { for (j=0; j<numBufs; j++) { datum = (data_t) __VERIFIER_nondet_int(); shouldReset = __VERIFIER_nondet_int(); datumOut = (data_t)0; if (shouldReset) bufReset(bufs[j], datum); else datumOut = bufRead(bufs[j], randomIdx(bufs[j])); } } return 1; }
int ChunkInputStream::readChunkContent(char *&pBuf, int &size, int &len) { int readLen = m_iRemain - 2; int ret; if (readLen > size) { readLen = size; ret = bufRead(pBuf, readLen, 0); } else ret = bufRead(pBuf, readLen, 1); if (ret > 0) { pBuf += ret; size -= ret; len += ret; m_iRemain -= ret; } return ret; }
int ChunkInputStream::skipTrailer() { char achBuf[128]; int ret; while (true) { ret = bufRead(achBuf, sizeof(achBuf), 1); if (ret <= 0) return ret; char *pBegin = achBuf; char *pEnd = &achBuf[ret]; while (pBegin < pEnd) { switch (m_iRemain) { case -3: pBegin = (char *)memchr(pBegin, '\n', pEnd - pBegin); if (pBegin) { ++m_iRemain; ++pBegin; } else pBegin = pEnd; break; case -2: if (*pBegin == '\r') ++m_iRemain; else if (*pBegin == '\n') { m_iChunkLen = CHUNK_EOF; m_iRemain = 0; return 1; } else m_iRemain = -3; ++pBegin; break; case -1: if (*pBegin == '\n') { m_iChunkLen = CHUNK_EOF; m_iRemain = 0; return 1; } else m_iRemain = -3; ++pBegin; break; } } } }
ssize_t SockStream::readline(void *vptr, size_t maxlen) { ssize_t rc; size_t n; char c, *ptr; ptr = (char *)vptr; for (n = 1; n < maxlen; n++) { if ( (rc = bufRead(&c)) == 1) { *ptr++ = c; if (c == '\n') break; /* newline is stored, like fgets() */ } else if (rc == 0) { *ptr = 0; return(n - 1); /* EOF, n - 1 bytes were read */ } else return(-1); /* error, errno set by read() */ } *ptr = 0; /* null terminate like fgets() */ return(n); }
static void tunnelDispatch(TunnelPtr tunnel) { if(circularBufferEmpty(&tunnel->buf1)) { if(tunnel->buf1.buf && !(tunnel->flags & (TUNNEL_READER1 | TUNNEL_WRITER2))) { dispose_chunk(tunnel->buf1.buf); tunnel->buf1.buf = NULL; tunnel->buf1.head = tunnel->buf1.tail = 0; } } if(circularBufferEmpty(&tunnel->buf2)) { if(tunnel->buf2.buf && !(tunnel->flags & (TUNNEL_READER2 | TUNNEL_WRITER1))) { dispose_chunk(tunnel->buf2.buf); tunnel->buf2.buf = NULL; tunnel->buf2.head = tunnel->buf2.tail = 0; } } if(tunnel->fd1 >= 0) { if(!(tunnel->flags & (TUNNEL_READER1 | TUNNEL_EOF1)) && !circularBufferFull(&tunnel->buf1)) { tunnel->flags |= TUNNEL_READER1; bufRead(tunnel->fd1, &tunnel->buf1, tunnelRead1Handler, tunnel); } if(!(tunnel->flags & (TUNNEL_WRITER1 | TUNNEL_EPIPE1)) && !circularBufferEmpty(&tunnel->buf2)) { tunnel->flags |= TUNNEL_WRITER1; /* There's no IO_NOTNOW in bufWrite, so it might close the file descriptor straight away. Wait until we're rescheduled. */ bufWrite(tunnel->fd1, &tunnel->buf2, tunnelWrite1Handler, tunnel); return; } if(tunnel->fd2 < 0 || (tunnel->flags & TUNNEL_EOF2)) { if(!(tunnel->flags & TUNNEL_EPIPE1)) shutdown(tunnel->fd1, 1); tunnel->flags |= TUNNEL_EPIPE1; } else if(tunnel->fd1 < 0 || (tunnel->flags & TUNNEL_EPIPE2)) { if(!(tunnel->flags & TUNNEL_EOF1)) shutdown(tunnel->fd1, 0); tunnel->flags |= TUNNEL_EOF1; } if((tunnel->flags & TUNNEL_EOF1) && (tunnel->flags & TUNNEL_EPIPE1)) { if(!(tunnel->flags & (TUNNEL_READER1 | TUNNEL_WRITER1))) { CLOSE(tunnel->fd1); tunnel->fd1 = -1; } } } if(tunnel->fd2 >= 0) { if(!(tunnel->flags & (TUNNEL_READER2 | TUNNEL_EOF2)) && !circularBufferFull(&tunnel->buf2)) { tunnel->flags |= TUNNEL_READER2; bufRead(tunnel->fd2, &tunnel->buf2, tunnelRead2Handler, tunnel); } if(!(tunnel->flags & (TUNNEL_WRITER2 | TUNNEL_EPIPE2)) && !circularBufferEmpty(&tunnel->buf1)) { tunnel->flags |= TUNNEL_WRITER2; bufWrite(tunnel->fd2, &tunnel->buf1, tunnelWrite2Handler, tunnel); return; } if(tunnel->fd1 < 0 || (tunnel->flags & TUNNEL_EOF1)) { if(!(tunnel->flags & TUNNEL_EPIPE2)) shutdown(tunnel->fd2, 1); tunnel->flags |= TUNNEL_EPIPE2; } else if(tunnel->fd1 < 0 || (tunnel->flags & TUNNEL_EPIPE1)) { if(!(tunnel->flags & TUNNEL_EOF2)) shutdown(tunnel->fd2, 0); tunnel->flags |= TUNNEL_EOF2; } if((tunnel->flags & TUNNEL_EOF2) && (tunnel->flags & TUNNEL_EPIPE2)) { if(!(tunnel->flags & (TUNNEL_READER2 | TUNNEL_WRITER2))) { CLOSE(tunnel->fd2); tunnel->fd2 = -1; } } } if(tunnel->fd1 < 0 && tunnel->fd2 < 0) destroyTunnel(tunnel); else assert(tunnel->flags & (TUNNEL_READER1 | TUNNEL_WRITER1 | TUNNEL_READER2 | TUNNEL_WRITER2)); }