public static Socket fork(ZContext ctx, IAttachedRunnable runnable, Object... args)
    {
        Socket pipe = ctx.createSocket(SocketType.PAIR);
        assert (pipe != null);
        pipe.bind(String.format(Locale.ENGLISH, "inproc://zctx-pipe-%d", pipe.hashCode()));

        //  Connect child pipe to our pipe
        ZContext ccontext = ctx.shadow();
        Socket cpipe = ccontext.createSocket(SocketType.PAIR);
        assert (cpipe != null);
        cpipe.connect(String.format(Locale.ENGLISH, "inproc://zctx-pipe-%d", pipe.hashCode()));

        //  Prepare child thread
        Thread shim = new ShimThread(ccontext, runnable, args, cpipe);
        shim.start();

        return pipe;
    }
@Test
    @Ignore
    public void testClosePipe()
    {
        ZContext ctx = new ZContext();
        Socket pipe = ZThread.fork(ctx, (args, ctx1, pipe1) -> {
            pipe1.recvStr();
            pipe1.send("pong");
        });

        assertThat(pipe, notNullValue());

        boolean rc = pipe.send("ping");
        assertThat(rc, is(true));

        String pong = pipe.recvStr();

        assertThat(pong, is("pong"));

        try {
            rc = pipe.send("boom ?!");
            assertThat("pipe was closed pretty fast", rc, is(true));
        }
        catch (ZMQException e) {
            int errno = e.getErrorCode();
            assertThat("Expected exception has the wrong code", ZError.ETERM, is(errno));
        }

        ctx.close();
    }