Ejemplo n.º 1
0
	static void MsgAssert(bool condition)
	{
		assert(condition);
		if ( !condition )
		{
			int error_code = zmq_errno();
			printf("error:%d", error_code);
		}
	}
Ejemplo n.º 2
0
static void run_test (int opt, T optval, int expected_error, int bounce_test)
{
    int rc;

    void *ctx = zmq_ctx_new ();
    assert (ctx);

    void *sb = zmq_socket (ctx, ZMQ_DEALER);
    assert (sb);

    if (opt) {
        rc = zmq_setsockopt(sb, opt, &optval, sizeof (optval));
        if (expected_error) {
            assert (rc == -1);
            assert (zmq_errno () == expected_error);
        } else {
            assert (rc == 0);
        }
    }

    void *sc = zmq_socket (ctx, ZMQ_DEALER);
    assert (sc);

    // If a test fails, don't hang for too long
    int timeout = 2500;
    rc = zmq_setsockopt (sb, ZMQ_RCVTIMEO, &timeout, sizeof (int));
    assert (rc == 0);
    rc = zmq_setsockopt (sb, ZMQ_SNDTIMEO, &timeout, sizeof (int));
    assert (rc == 0);
    rc = zmq_setsockopt (sc, ZMQ_RCVTIMEO, &timeout, sizeof (int));
    assert (rc == 0);
    rc = zmq_setsockopt (sc, ZMQ_SNDTIMEO, &timeout, sizeof (int));
    assert (rc == 0);
    int interval = -1;
    rc = zmq_setsockopt (sc, ZMQ_RECONNECT_IVL, &interval, sizeof (int));
    assert (rc == 0);

    if (bounce_test) {
        const char* endpoint = "ipc://test_filter_ipc.sock";
        int rc = zmq_bind (sb, endpoint);
        assert (rc == 0);

        rc = zmq_connect (sc, endpoint);
        assert (rc == 0);
        
        if (bounce_test > 0)
            bounce (sb, sc);
        else
            bounce_fail (sb, sc);
    }

    close_zero_linger (sc);
    close_zero_linger (sb);

    rc = zmq_ctx_term (ctx);
    assert (rc == 0);
}
Ejemplo n.º 3
0
 inline size_t send (const void *buf_, size_t len_, int flags_ = 0)
 {
     int nbytes = zmq_send (ptr, buf_, len_, flags_);
     if (nbytes >= 0)
         return (size_t) nbytes;
     if (zmq_errno () == EAGAIN)
         return 0;
     throw error_t ();
 }
Ejemplo n.º 4
0
static int Lzmq_push_error(lua_State *L)
{
    const char *error;
    lua_pushnil(L);
    switch(zmq_errno()) {
    case EAGAIN:
        lua_pushliteral(L, "timeout");
        break;
    case ETERM:
        lua_pushliteral(L, "closed");
        break;
    default:
        error = zmq_strerror(zmq_errno());
        lua_pushlstring(L, error, strlen(error));
        break;
    }
    return 2;
}
Ejemplo n.º 5
0
// Finalizer for context
void finalize_context( value v) {
	gc_enter_blocking();
	int ret = zmq_term( val_data(v));
	gc_exit_blocking();
	if (ret != 0) {
		int err = zmq_errno();
		val_throw(alloc_int(err));
	}
}
Ejemplo n.º 6
0
static int pollitem_on_output(void *socket, void *ehub, void *data) {
   int r;
   char *message = ehub_on_output(ehub, socket, data);

   r = zmq_send(socket, message, strlen(message), 0);
   if (r==-1) return zmq_errno();

   return 0;
}
Ejemplo n.º 7
0
 inline bool recv (message_t *msg_, int flags_ = 0)
 {
     int nbytes = zmq_msg_recv (&(msg_->msg), ptr, flags_);
     if (nbytes >= 0)
         return true;
     if (zmq_errno () == EAGAIN)
         return false;
     throw error_t ();
 }
Ejemplo n.º 8
0
 inline bool recv (message_t *msg_, int flags_ = 0)
 {
     int rc = zmq_recv (ptr, msg_, flags_);
     if (rc == 0)
         return true;
     if (rc == -1 && zmq_errno () == EAGAIN)
         return false;
     throw error_t ();
 }
Ejemplo n.º 9
0
 inline bool send (message_t &msg_, int flags_ = 0)
 {
     int nbytes = zmq_msg_send (&(msg_), ptr, flags_);
     if (nbytes >= 0)
         return true;
     if (zmq_errno () == EAGAIN)
         return false;
     throw error_t ();
 }
Ejemplo n.º 10
0
void test_send_one_connected_one_unconnected ()
{
    int val;
    // TEST 1.
    // First we're going to attempt to send messages to two
    // pipes, one connected, the other not. We should see
    // the PUSH load balancing to both pipes, and hence half
    // of the messages getting queued, as connect() creates a
    // pipe immediately.

    void *to = test_context_socket (ZMQ_PULL);

    // Bind the one valid receiver
    val = 0;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (to, ZMQ_LINGER, &val, sizeof (val)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (to, "tipc://{6555,0,0}"));

    // Create a socket pushing to two endpoints - only 1 message should arrive.
    void *from = test_context_socket (ZMQ_PUSH);

    val = 0;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (from, ZMQ_LINGER, &val, sizeof (val)));
    // This pipe will not connect
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (from, "tipc://{5556,0}@0.0.0"));
    // This pipe will
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (from, "tipc://{6555,0}@0.0.0"));

    // We send 10 messages, 5 should just get stuck in the queue
    // for the not-yet-connected pipe
    const int send_count = 10;
    for (int i = 0; i < send_count; ++i) {
        send_string_expect_success (from, "Hello", 0);
    }

    // We now consume from the connected pipe
    // - we should see just 5
    int timeout = SETTLE_TIME;
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_setsockopt (to, ZMQ_RCVTIMEO, &timeout, sizeof (int)));

    int seen = 0;
    while (true) {
        char buffer[16];
        int rc = zmq_recv (to, &buffer, sizeof (buffer), 0);
        if (rc == -1) {
            TEST_ASSERT_EQUAL_INT (EAGAIN, zmq_errno ());
            break; //  Break when we didn't get a message
        }
        seen++;
    }
    TEST_ASSERT_EQUAL_INT (send_count / 2, seen);

    test_context_socket_close (from);
    test_context_socket_close (to);
}
OpenEphysNetworkEventsClient::~OpenEphysNetworkEventsClient() {
    if (zmqSocket) {
        if (0 != zmq_disconnect(zmqSocket.get(), endpoint.c_str()) &&
            ENOENT != zmq_errno())
        {
            logZMQError("Unable to disconnect from Open Ephys network events module");
        }
    }
}
Ejemplo n.º 12
0
int main (void)
{
    setup_test_environment();
    size_t len = MAX_SOCKET_STRING;
    char my_endpoint[MAX_SOCKET_STRING];
    void *ctx = zmq_ctx_new ();
    assert (ctx);

    //  Spawn ZAP handler
    //  We create and bind ZAP socket in main thread to avoid case
    //  where child thread does not start up fast enough.
    void *handler = zmq_socket (ctx, ZMQ_REP);
    assert (handler);
    int rc = zmq_bind (handler, "inproc://zeromq.zap.01");
    assert (rc == 0);
    void *zap_thread = zmq_threadstart (&zap_handler, handler);

    void *server = zmq_socket (ctx, ZMQ_DEALER);
    assert (server);
    void *client = zmq_socket (ctx, ZMQ_DEALER);
    assert (client);
    rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "DOMAIN", 6);
    assert (rc == 0);
    rc = zmq_bind (server, "tcp://127.0.0.1:*");
    assert (rc == 0);
    rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
    assert (rc == 0);
    rc = zmq_connect (client, my_endpoint);
    assert (rc == 0);

    s_send (client, "This is a message");
    zmq_msg_t msg;
    zmq_msg_init (&msg);
    rc = zmq_msg_recv (&msg, server, 0);
    assert (rc != -1);
    assert (streq (zmq_msg_gets (&msg, "Hello"), "World"));
    assert (streq (zmq_msg_gets (&msg, "Socket-Type"), "DEALER"));
    assert (streq (zmq_msg_gets (&msg, "User-Id"), "anonymous"));
    assert (streq (zmq_msg_gets (&msg, "Peer-Address"), "127.0.0.1"));

    assert (zmq_msg_gets (&msg, "No Such") == NULL);
    assert (zmq_errno () == EINVAL);
    zmq_msg_close (&msg);

    close_zero_linger (client);
    close_zero_linger (server);

    //  Shutdown
    rc = zmq_ctx_term (ctx);
    assert (rc == 0);

    //  Wait until ZAP handler terminates
    zmq_threadclose (zap_thread);

    return 0;
}
Ejemplo n.º 13
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
static void
wrap_zmq_term(zmq_drv_t *drv)
{
    zmqdrv_fprintf("term %p\r\n", drv->zmq_context);

    if (0 < drv->zmq_pid_socket.size())
    {
        for (zmq_pid_socket_map_t::iterator it = drv->zmq_pid_socket.begin(); it != drv->zmq_pid_socket.end(); ++it)
        {
            zmq_sock_info* si = it->second;

            if (si->busy)
            {
                // Remove socket from erlang vm polling
                driver_select(drv->port, si->fd, ERL_DRV_READ, 0);

                if (si->out_caller)
                {
                    reply_error(drv->port, si->out_caller, ETERM);
                    si->out_caller = 0;
                    zmq_msg_close(&si->out_msg);
                }
                if (si->in_caller)
                {
                    reply_error(drv->port, si->in_caller, ETERM);
                    si->in_caller = 0;
                }
                if (si->poll_caller)
                {
                    send_events(drv->port, si->poll_caller, (uint32_t)ZMQ_POLLERR);
                    si->poll_caller = 0;
                }

                si->busy = false;
            }
        }

        // TODO: Remove if zeromq itself ever gets fixed. As zmq_term() is a
        // blocking call, and will not return until all sockets are closed,
        // so do not allow it to be called while there are open sockets.
        drv->terminating = true;
        reply_error(drv->port, driver_caller(drv->port), EAGAIN);
        return;
    }

    // cross fingers and hope zmq_term() doesn't block, else we hardlock.
    if (0 != zmq_term(drv->zmq_context))
    {
        reply_error(drv->port, driver_caller(drv->port), zmq_errno());
        return;
    }

    drv->zmq_context = NULL;

    reply_ok(drv->port, driver_caller(drv->port));
}
Ejemplo n.º 14
0
		void * teRDNetwork::GetData(u32 & dataSize)
		{
			if(!zmqContext)
				return NULL;

			zmq_msg_init(&getDataRequest);
			s32 errCode = zmq_recv(zmqDataDrop, &getDataRequest, 0);
			if(errCode != 0)
			{
				if(zmq_errno() != EAGAIN)
					TE_LOG_WRN("0mq recv data err %i : %i", errCode, zmq_errno());

				return NULL;
			}

			dataSize = zmq_msg_size(&getDataRequest);

			return zmq_msg_data(&getDataRequest);
		}
Ejemplo n.º 15
0
static void
zmqdrv_recv(zmq_drv_t *drv, ErlIOVec *ev)
{
    ErlDrvBinary*  bin   = ev->binv[1];
    char*          bytes = bin->orig_bytes;
    uint32_t       idx   = ntohl(*(uint32_t*)(bytes+1));
    zmq_sock_info* si    = drv->get_socket_info(idx);

    if (idx > drv->zmq_socket_count || !si) {
        zmqdrv_error_code(drv, ENODEV);
        return;
    }

    if (si->active_mode) {
        zmqdrv_error_code(drv, EINVAL);
        return;
    }

    if (si->in_caller != 0) {
        // Previous recv() call in passive mode didn't complete.
        // The owner must be blocked waiting for result.
        zmqdrv_error_code(drv, EBUSY);
        return;
    }

    uint32_t events;
    size_t events_size = sizeof(events);
    zmq_getsockopt(si->socket, ZMQ_EVENTS, &events, &events_size);

    if (events == 0)
        si->in_caller = driver_caller(drv->port);
    else {
        msg_t msg;

        if (zmq_recv(si->socket, &msg, ZMQ_NOBLOCK) == 0)
            zmqdrv_ok_binary(drv, driver_caller(drv->port), zmq_msg_data(&msg), zmq_msg_size(&msg));
        else if (zmq_errno() == EAGAIN) {
            // No input available. Make the caller wait by not returning result
            si->in_caller = driver_caller(drv->port);
        } else
            zmqdrv_error_code(drv, zmq_errno());
    }
}
Ejemplo n.º 16
0
effBOOL EFFNetServer::Bind(effString address)
{
	if ( zmq_bind(socket, EFFSTRING2ANSI(address)) == -1 )
	{
		std::string error = zmq_strerror(zmq_errno());
		return effFALSE;
	}

	return effTRUE;
}
Ejemplo n.º 17
0
void zmq::tcp_listener_t::in_event ()
{
    fd_t fd = accept ();

    //  If connection was reset by the peer in the meantime, just ignore it.
    //  TODO: Handle specific errors like ENFILE/EMFILE etc.
    if (fd == retired_fd) {
        socket->event_accept_failed (endpoint, zmq_errno ());
        return;
    }

    int rc = tune_tcp_socket (fd);
    rc = rc
         | tune_tcp_keepalives (
             fd, options.tcp_keepalive, options.tcp_keepalive_cnt,
             options.tcp_keepalive_idle, options.tcp_keepalive_intvl);
    rc = rc | tune_tcp_maxrt (fd, options.tcp_maxrt);
    if (rc != 0) {
        socket->event_accept_failed (endpoint, zmq_errno ());
        return;
    }

    //  Create the engine object for this connection.
    stream_engine_t *engine =
      new (std::nothrow) stream_engine_t (fd, options, endpoint);
    alloc_assert (engine);

    //  Choose I/O thread to run connecter in. Given that we are already
    //  running in an I/O thread, there must be at least one available.
    io_thread_t *io_thread = choose_io_thread (options.affinity);
    zmq_assert (io_thread);

    //  Create and launch a session object.
    session_base_t *session =
      session_base_t::create (io_thread, false, socket, options, NULL);
    errno_assert (session);
    session->inc_seqnum ();
    launch_child (session);
    send_attach (session, engine, false);
    socket->event_accepted (endpoint, (int) fd);
}
Ejemplo n.º 18
0
void test__zmq_curve_public__valid__success ()
{
    // These are paired according to hintjens.com/blog:45
    static const char public_key[] = "Yne@$w-vo<fVvi]a<NY6T1ed:M$fCG*[IaLV{hID";
    static const char secret_key[] = "D:)Q[IlAW!ahhC2ac:9*A}h:p?([4%wOTJ%JR%cs";

    errno = 0;
    char out_public[41] = {0};

    const int rc = zmq_curve_public (out_public, secret_key);

#if defined(ZMQ_HAVE_CURVE)
    assert (rc == 0);
    assert (zmq_errno () == 0);
    assert (streq (out_public, public_key));
#else
    assert (rc == -1);
    assert (zmq_errno () == ENOTSUP);
    (void) public_key;
#endif
}
Ejemplo n.º 19
0
static int pollitem_on_input(void *socket, void *ehub, void *data) {
   zmq_msg_t msg;
   int r, n;
   char *message;

   r = zmq_msg_init(&msg);
   if (r==-1) return zmq_errno();

   n = zmq_msg_recv(&msg, socket, 0);
   if (n==-1) return zmq_errno();

   message = malloc(n + 1);
   if (!message) return ENOMEM;
   memcpy(message, zmq_msg_data(&msg), n);

   r = zmq_msg_close(&msg);
   if (r==-1) return zmq_errno();

   ehub_on_input(ehub, socket, message, data);
   free(message);
}
Ejemplo n.º 20
0
Return<std::string> ClientZmq::connect() {
  if (socket == NULL){
    return Return<std::string> (false, "Socket not initialized");
  }
  
  if (zmq_connect (socket, endPoint.c_str()) != 0){
    std::cout << "End Point " << endPoint << std::endl;
    return Return<std::string>(false, zmq_strerror(zmq_errno()));
  } else {
    return true;
  }
}
Ejemplo n.º 21
0
int zmq::ipc_connecter_t::close ()
{
    zmq_assert (s != retired_fd);
    int rc = ::close (s);
    if (rc != 0) {
        session->monitor_event (ZMQ_EVENT_CLOSE_FAILED, endpoint.c_str(), zmq_errno());
        return -1;
    }
    session->monitor_event (ZMQ_EVENT_CLOSED, endpoint.c_str(), s);
    s = retired_fd;
    return 0;
}
Ejemplo n.º 22
0
	Bool CZmq::FillErr()
	{
		m_iErrCode = zmq_errno();

#ifdef _DEBUG
		m_sErrMsg  = zmq_strerror(m_iErrCode);

		FmtPrint("ZmqError, Errno: %d, Errmsg: %s", m_iErrCode, m_sErrMsg.c_str());
#endif

		return true;
	}
Ejemplo n.º 23
0
    context_t::context_t(/*TODO: add options*/) {
      //make the c context
      auto* context = zmq_ctx_new();
      if(!context)
        throw std::runtime_error(zmq_strerror(zmq_errno()));

      //wrap it in RAII goodness
      ptr.reset(context,
        [](void* context) {
          assert(zmq_ctx_term(context) == 0);
        });
    }
Ejemplo n.º 24
0
    socket_t::socket_t(const context_t& context, int socket_type):context(context) {
      //make the c socket
      auto* socket = zmq_socket(this->context, socket_type);
      if(!socket)
        throw std::runtime_error(zmq_strerror(zmq_errno()));

      //wrap it in RAII goodness
      ptr.reset(socket,
        [](void* socket){
          assert(zmq_close(socket) == 0);
        });
    }
Ejemplo n.º 25
0
SEXP R_zmq_msg_recv(SEXP R_socket, SEXP R_flags){
	SEXP R_rmsg = R_NilValue;
	int C_rmsg_length;
	int C_ret = -1, C_errno, C_flags = INTEGER(R_flags)[0];
	void *C_socket = R_ExternalPtrAddr(R_socket);
	zmq_msg_t msg;

	if(C_socket != NULL){
		C_ret = zmq_msg_init(&msg);
		if(C_ret == -1){
			C_errno = zmq_errno();
			REprintf("R_zmq_msg_init errno: %d strerror: %s\n",
				C_errno, zmq_strerror(C_errno));
		}

		C_ret = zmq_msg_recv(&msg, C_socket, C_flags);
		if(C_ret == -1){
			C_errno = zmq_errno();
			REprintf("R_zmq_msg_recv errno: %d strerror: %s\n",
				C_errno, zmq_strerror(C_errno));
		}
		C_rmsg_length = zmq_msg_size(&msg);
		PROTECT(R_rmsg = allocVector(RAWSXP, C_rmsg_length));
		memcpy(RAW(R_rmsg), zmq_msg_data(&msg), C_rmsg_length);

		C_ret = zmq_msg_close(&msg);
		if(C_ret == -1){
			C_errno = zmq_errno();
			REprintf("R_zmq_msg_close errno: %d strerror: %s\n",
				C_errno, zmq_strerror(C_errno));
		}

		UNPROTECT(1);
		return(R_rmsg);
	} else{
		REprintf("R_zmq_send: C_socket is not available.\n");
	}

	return(R_rmsg);
} /* End of R_zmq_msg_recv(). */
Ejemplo n.º 26
0
Archivo: Zmq.cpp Proyecto: trax44/tvirt
Return<int> Zmq::recv(std::string *data) {
  zmq_msg_t part;
  Return<int> ret(true, 0);

  if (socket == NULL){
    ret.success = false;
    data->append("Socket not initialized");
    return ret;
  }
  std::cout << "recv" << std::endl;

  ret.data = zmq_msg_init (&part);
  
  if (ret.data != 0){
    data->append(zmq_strerror(zmq_errno()));
    ret.success = false;
    return ret;
  }
  
  ret.data = zmq_msg_recv (&part, socket, 0);
  
  if (ret.data == -1){
    zmq_msg_close (&part); 
    data->append(zmq_strerror(zmq_errno()));
    ret.success = false;
    return ret;
  }

  ret.success = true;
  data->append(static_cast<char*>(zmq_msg_data (&part)), 
               zmq_msg_size(&part));
  

  ret.success = zmq_msg_more(&part);
  
  zmq_msg_close (&part); 


  return ret;
}
Ejemplo n.º 27
0
    bool publish( const zerobuf::Zerobuf& zerobuf )
    {
        // TODO: Save type in zerobuf and transmit in one message
#ifdef COMMON_LITTLEENDIAN
        const uint128_t& type = zerobuf.getZerobufType();
#else
        uint128_t type = zerobuf.getZerobufType();
        detail::byteswap( type ); // convert to little endian wire protocol
#endif
        const void* data = zerobuf.getZerobufData();

        zmq_msg_t msgHeader;
        zmq_msg_init_size( &msgHeader, sizeof( type ));
        memcpy( zmq_msg_data( &msgHeader ), &type, sizeof( type ));
        int ret = zmq_msg_send( &msgHeader, socket,
                                data ? ZMQ_SNDMORE : 0 );
        zmq_msg_close( &msgHeader );
        if( ret == -1 )
        {
            ZEQWARN << "Cannot publish message header, got "
                   << zmq_strerror( zmq_errno( )) << std::endl;
            return false;
        }

        if( !data )
            return true;

        zmq_msg_t msg;
        zmq_msg_init_size( &msg, zerobuf.getZerobufSize( ));
        ::memcpy( zmq_msg_data(&msg), data, zerobuf.getZerobufSize( ));
        ret = zmq_msg_send( &msg, socket, 0 );
        zmq_msg_close( &msg );
        if( ret  == -1 )
        {
            ZEQWARN << "Cannot publish message data, got "
                    << zmq_strerror( zmq_errno( )) << std::endl;
            return false;
        }
        return true;
    }
Ejemplo n.º 28
0
/**
 * Issue a read on the socket.
 */
static zmq_msg_t* do_read(JNIEnv *env, jobject obj, zmq_msg_t *message, int flags)
{
    void *s = get_socket (env, obj, 1);

    int rc = zmq_msg_init (message);
    int err = zmq_errno();
    if (rc != 0) {
        raise_exception (env, err);
        return NULL;
    }

#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
    rc = zmq_recvmsg (s, message, flags);
#else
    rc = zmq_recv (s, message, flags);
#endif
    err = zmq_errno();
    if (rc < 0 && err == EAGAIN) {
        rc = zmq_msg_close (message);
        err = zmq_errno();
        if (rc != 0) {
            raise_exception (env, err);
            return NULL;
        }
        return NULL;
    }

    if (rc < 0) {
        raise_exception (env, err);
        rc = zmq_msg_close (message);
        err = zmq_errno();
        if (rc != 0) {
            raise_exception (env, err);
            return NULL;
        }
        return NULL;
    }
    
    return message;
}
Ejemplo n.º 29
0
// Test vector: rfc.zeromq.org/spec:32/Z85
void test__zmq_z85_decode__valid__success ()
{
    static const size_t size = 10 * 4 / 5;
    static const uint8_t expected[size] = {0x86, 0x4F, 0xD2, 0x6F,
                                           0xB5, 0x59, 0xF7, 0x5B};
    static const char *encoded = "HelloWorld";
    uint8_t out_decoded[size] = {0};

    errno = 0;
    assert (zmq_z85_decode (out_decoded, encoded) != NULL);
    assert (zmq_errno () == 0);
    assert (memcmp (out_decoded, expected, size) == 0);
}
Ejemplo n.º 30
0
	inline int send_data_more(void * socket, const void * data, size_t len){
		zmq_msg_t msg;
		int rc = zmq_msg_init_size(&msg, len);
		assert(rc == 0);
		memcpy(zmq_msg_data(&msg), data, len);
		rc = zmq_msg_send(&msg, socket, ZMQ_SNDMORE);
		if (rc < 0){
			cout << "zmq_msg_send: " << zmq_strerror(zmq_errno());
		}
		assert(rc >= 0);
		zmq_msg_close(&msg);
		return rc;
	}