Alien-uv

 view release on metacpan or  search on metacpan

libuv/test/test-ipc-send-recv.c  view on Meta::CPAN

 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "uv.h"
#include "task.h"

#include <stdio.h>
#include <string.h>

/* See test-ipc.c */
void spawn_helper(uv_pipe_t* channel,
                  uv_process_t* process,
                  const char* helper);

void ipc_send_recv_helper_threadproc(void* arg);

union handles {
  uv_handle_t handle;
  uv_stream_t stream;
  uv_pipe_t pipe;
  uv_tcp_t tcp;
  uv_tty_t tty;
};

struct test_ctx {
  uv_pipe_t channel;
  uv_connect_t connect_req;
  uv_write_t write_req;
  uv_write_t write_req2;
  uv_handle_type expected_type;
  union handles send;
  union handles send2;
  union handles recv;
  union handles recv2;
};

struct echo_ctx {
  uv_pipe_t listen;
  uv_pipe_t channel;
  uv_write_t write_req;
  uv_write_t write_req2;
  uv_handle_type expected_type;
  union handles recv;
  union handles recv2;
};

static struct test_ctx ctx;
static struct echo_ctx ctx2;

/* Used in write2_cb to decide if we need to cleanup or not */
static int is_child_process;
static int is_in_process;
static int read_cb_count;
static int recv_cb_count;
static int write2_cb_called;


static void alloc_cb(uv_handle_t* handle,
                     size_t suggested_size,
                     uv_buf_t* buf) {
  /* we're not actually reading anything so a small buffer is okay */
  static char slab[8];
  buf->base = slab;
  buf->len = sizeof(slab);
}


static void recv_cb(uv_stream_t* handle,
                    ssize_t nread,
                    const uv_buf_t* buf) {
  uv_handle_type pending;
  uv_pipe_t* pipe;
  int r;
  union handles* recv;

  pipe = (uv_pipe_t*) handle;
  ASSERT(pipe == &ctx.channel);

  do {
    if (++recv_cb_count == 1) {
      recv = &ctx.recv;
    } else {
      recv = &ctx.recv2;
    }

    /* Depending on the OS, the final recv_cb can be called after
     * the child process has terminated which can result in nread
     * being UV_EOF instead of the number of bytes read.  Since
     * the other end of the pipe has closed this UV_EOF is an
     * acceptable value. */
    if (nread == UV_EOF) {
      /* UV_EOF is only acceptable for the final recv_cb call */
      ASSERT(recv_cb_count == 2);
    } else {
      ASSERT(nread >= 0);
      ASSERT(uv_pipe_pending_count(pipe) > 0);

      pending = uv_pipe_pending_type(pipe);
      ASSERT(pending == ctx.expected_type);

      if (pending == UV_NAMED_PIPE)
        r = uv_pipe_init(ctx.channel.loop, &recv->pipe, 0);
      else if (pending == UV_TCP)
        r = uv_tcp_init(ctx.channel.loop, &recv->tcp);
      else
        abort();
      ASSERT(r == 0);

      r = uv_accept(handle, &recv->stream);
      ASSERT(r == 0);



( run in 1.018 second using v1.01-cache-2.11-cpan-13bb782fe5a )