FAR void *nxcon_listener(FAR void *arg) { int ret; /* Process events forever */ for (;;) { /* Handle the next event. If we were configured blocking, then * we will stay right here until the next event is received. Since * we have dedicated a while thread to servicing events, it would * be most natural to also select CONFIG_NX_BLOCKING -- if not, the * following would be a tight infinite loop (unless we added addition * logic with nx_eventnotify and sigwait to pace it). */ ret = nx_eventhandler(g_nxcon_vars.hnx); if (ret < 0) { /* An error occurred... assume that we have lost connection with * the server. */ message("nxcon_listener: Lost server connection: %d\n", errno); exit(EXIT_FAILURE); } /* If we received a message, we must be connected */ if (!g_nxcon_vars.connected) { g_nxcon_vars.connected = true; sem_post(&g_nxcon_vars.eventsem); message("nxcon_listener: Connected\n"); } } }
NXHANDLE nx_connectinstance(FAR const char *svrmqname) { FAR struct nxfe_conn_s *conn; struct nxsvrmsg_s msg; char climqname[NX_CLIENT_MXNAMELEN]; struct mq_attr attr; int ret; /* Sanity checking */ #ifdef CONFIG_DEBUG if (!svrmqname) { errno = EINVAL; return NULL; } #endif /* Allocate the NX client structure */ conn = (FAR struct nxfe_conn_s *)zalloc(sizeof(struct nxfe_conn_s)); if (!conn) { errno = ENOMEM; goto errout; } /* Create the client MQ name */ nxmu_semtake(&g_nxlibsem); conn->cid = g_nxcid++; nxmu_semgive(&g_nxlibsem); sprintf(climqname, NX_CLIENT_MQNAMEFMT, conn->cid); /* Open the client MQ for reading */ attr.mq_maxmsg = CONFIG_NX_MXCLIENTMSGS; attr.mq_msgsize = NX_MXCLIMSGLEN; attr.mq_flags = 0; #ifdef CONFIG_NX_BLOCKING conn->crdmq = mq_open(climqname, O_RDONLY|O_CREAT, 0666, &attr); #else conn->crdmq = mq_open(climqname, O_RDONLY|O_CREAT|O_NONBLOCK, 0666, &attr); #endif if (conn->crdmq == (mqd_t)-1) { gdbg("mq_open(%s) failed: %d\n", climqname, errno); goto errout_with_conn; } /* Open the server MQ for writing */ attr.mq_maxmsg = CONFIG_NX_MXSERVERMSGS; attr.mq_msgsize = NX_MXSVRMSGLEN; attr.mq_flags = 0; conn->cwrmq = mq_open(svrmqname, O_WRONLY|O_CREAT, 0666, &attr); if (conn->cwrmq == (mqd_t)-1) { gdbg("mq_open(%s) failed: %d\n", svrmqname, errno); goto errout_with_rmq; } /* Inform the server that this client exists */ msg.msgid = NX_SVRMSG_CONNECT; msg.conn = conn; ret = mq_send(conn->cwrmq, &msg, sizeof(struct nxsvrmsg_s), NX_SVRMSG_PRIO); if (ret < 0) { gdbg("mq_send failed: %d\n", errno); goto errout_with_wmq; } #if 0 /* Now read until we get a response to this message. The server will * respond with either (1) NX_CLIMSG_CONNECTED, in which case the state * will change to NX_CLISTATE_CONNECTED, or (2) NX_CLIMSG_DISCONNECTED * in which case, nx_message will fail with errno = EHOSTDOWN. */ do { ret = nx_eventhandler((NXHANDLE)conn); if (ret < 0) { gdbg("nx_message failed: %d\n", errno); goto errout_with_wmq; } usleep(300000); } while (conn->state != NX_CLISTATE_CONNECTED); #endif return (NXHANDLE)conn; errout_with_wmq: mq_close(conn->cwrmq); errout_with_rmq: mq_close(conn->crdmq); errout_with_conn: free(conn); errout: return NULL; }