zctx_t * zctx_shadow (zctx_t *ctx) { assert (ctx); // Initialize the original context now if necessary if (!ctx->context) { zctx__initialize_underlying (ctx); if (!ctx->context) return NULL; } // Shares same 0MQ context but has its own list of sockets so that // we create, use, and destroy sockets only within a single thread. zctx_t *self = (zctx_t *) zmalloc (sizeof (zctx_t)); if (!self) return NULL; self->sockets = zlist_new (); self->mutex = zmutex_new (); if (!self->sockets || !self->mutex) { zlist_destroy (&self->sockets); zmutex_destroy (&self->mutex); free (self); return NULL; } self->context = ctx->context; self->pipehwm = ctx->pipehwm; self->sndhwm = ctx->sndhwm; self->rcvhwm = ctx->rcvhwm; self->linger = ctx->linger; self->shadow = true; // This is a shadow context return self; }
void * zctx__socket_new (zctx_t *self, int type) { // Initialize context now if necessary assert (self); if (!self->context) { zctx__initialize_underlying (self); if (!self->context) return NULL; } // Create and register socket void *zocket = zmq_socket (self->context, type); if (!zocket) return NULL; #if (ZMQ_VERSION_MAJOR == 2) // For ZeroMQ/2.x we use sndhwm for both send and receive zsocket_set_hwm (zocket, self->sndhwm); #else // For later versions we use separate SNDHWM and RCVHWM zsocket_set_sndhwm (zocket, self->sndhwm); zsocket_set_rcvhwm (zocket, self->rcvhwm); #endif zmutex_lock (self->mutex); if (zlist_push (self->sockets, zocket)) { zmutex_unlock (self->mutex); zmq_close (zocket); return NULL; } zmutex_unlock (self->mutex); return zocket; }
zctx_t * zctx_shadow (zctx_t *ctx) { assert (ctx); // Initialize the original context now if necessary if (!ctx->context) { zctx__initialize_underlying (ctx); if (!ctx->context) return NULL; } zctx_t *self = zctx_shadow_zmq_ctx (ctx->context); if (self) { // copy high water marks and linger from old context self->pipehwm = ctx->pipehwm; self->sndhwm = ctx->sndhwm; self->rcvhwm = ctx->rcvhwm; self->linger = ctx->linger; } return self; }