static void collect_data_to_send (client_t *self) { zsys_info ("read %d bytes", (int) zpipes_msg_size (self->request)); // Do we have enough data to satisfy the read request? size_t required = zpipes_msg_size (self->request); // If pipe was closed, we'll do a short read with as much // data as we have pending if (required > self->pending && self->pipe == NULL) required = self->pending; if (self->pipe == NULL && self->pending == 0) engine_set_exception (self, pipe_shut_event); else if (self->pending >= required) { // Create a bucket chunk with the required max size zchunk_t *bucket = zchunk_new (NULL, required); // Now fill the bucket with chunks from our queue while (zchunk_size (bucket) < required) { // Get next chunk and consume as much of it as possible zchunk_t *chunk = (zchunk_t *) zlist_pop (self->queue); assert (chunk); zchunk_consume (bucket, chunk); // If chunk is exhausted, destroy it if (zchunk_exhausted (chunk)) zchunk_destroy (&chunk); else { // Push chunk back for next time zlist_push (self->queue, chunk); assert (zchunk_size (bucket) == required); } } zpipes_msg_set_chunk (self->reply, &bucket); self->pending -= required; } else engine_set_exception (self, not_enough_data_event); }
ssize_t zpipes_client_write (zpipes_client_t *self, void *data, size_t size, int timeout) { assert (self); zchunk_t *chunk = zchunk_new (data, size); assert (chunk); zpipes_msg_t *request = zpipes_msg_new (ZPIPES_MSG_WRITE); zpipes_msg_set_chunk (request, &chunk); zpipes_msg_set_timeout (request, timeout); zpipes_msg_send (&request, self->dealer); zpipes_msg_t *reply = zpipes_msg_recv (self->dealer); if (!reply) { self->error = EINTR; return -1; // Interrupted } ssize_t rc = size; if (zpipes_msg_id (reply) == ZPIPES_MSG_WRITE_TIMEOUT) { self->error = EAGAIN; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_WRITE_FAILED) { // TODO: better error code? // This happens if we close a pipe while there's a pending write self->error = EINTR; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_INVALID) { self->error = EBADF; rc = -1; } zpipes_msg_destroy (&reply); return rc; }