int MQTTClient_disconnect1(MQTTClient handle, int timeout, int internal, int stop) { MQTTClients* m = handle; START_TIME_TYPE start; int rc = MQTTCLIENT_SUCCESS; int was_connected = 0; FUNC_ENTRY; Thread_lock_mutex(mqttclient_mutex); if (m == NULL || m->c == NULL) { rc = MQTTCLIENT_FAILURE; goto exit; } if (m->c->connected == 0 && m->c->connect_state == 0) { rc = MQTTCLIENT_DISCONNECTED; goto exit; } was_connected = m->c->connected; /* should be 1 */ if (m->c->connected != 0) { start = MQTTClient_start_clock(); m->c->connect_state = -2; /* indicate disconnecting */ while (m->c->inboundMsgs->count > 0 || m->c->outboundMsgs->count > 0) { /* wait for all inflight message flows to finish, up to timeout */ if (MQTTClient_elapsed(start) >= timeout) break; Thread_unlock_mutex(mqttclient_mutex); MQTTClient_yield(); Thread_lock_mutex(mqttclient_mutex); } } MQTTClient_closeSession(m->c); while (Thread_check_sem(m->connect_sem)) Thread_wait_sem(m->connect_sem, 100); while (Thread_check_sem(m->connack_sem)) Thread_wait_sem(m->connack_sem, 100); while (Thread_check_sem(m->suback_sem)) Thread_wait_sem(m->suback_sem, 100); while (Thread_check_sem(m->unsuback_sem)) Thread_wait_sem(m->unsuback_sem, 100); exit: if (stop) MQTTClient_stop(); if (internal && m->cl && was_connected) { Log(TRACE_MIN, -1, "Calling connectionLost for client %s", m->c->clientID); Thread_start(connectionLost_call, m); } Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
thread_return_type secondary(void* n) { int rc = 0; /* cond_type cond = n; printf("Secondary thread about to wait\n"); rc = Thread_wait_cond(cond); printf("Secondary thread returned from wait %d\n", rc);*/ sem_type sem = n; printf("Secondary thread about to wait\n"); rc = Thread_wait_sem(sem); printf("Secondary thread returned from wait %d\n", rc); printf("Secondary thread about to wait\n"); rc = Thread_wait_sem(sem); printf("Secondary thread returned from wait %d\n", rc); printf("Secondary check sem %d\n", Thread_check_sem(sem)); return 0; }
MQTTPacket* MQTTClient_waitfor(MQTTClient handle, int packet_type, int* rc, long timeout) { MQTTPacket* pack = NULL; MQTTClients* m = handle; START_TIME_TYPE start = MQTTClient_start_clock(); FUNC_ENTRY; if (((MQTTClients*)handle) == NULL) { *rc = MQTTCLIENT_FAILURE; goto exit; } if (running) { if (packet_type == CONNECT) { if ((*rc = Thread_wait_sem(m->connect_sem, timeout)) == 0) *rc = m->rc; } else if (packet_type == CONNACK) *rc = Thread_wait_sem(m->connack_sem, timeout); else if (packet_type == SUBACK) *rc = Thread_wait_sem(m->suback_sem, timeout); else if (packet_type == UNSUBACK) *rc = Thread_wait_sem(m->unsuback_sem, timeout); if (*rc == 0 && packet_type != CONNECT && m->pack == NULL) Log(LOG_ERROR, -1, "waitfor unexpectedly is NULL for client %s, packet_type %d, timeout %ld", m->c->clientID, packet_type, timeout); pack = m->pack; } else { *rc = TCPSOCKET_COMPLETE; while (1) { int sock = -1; pack = MQTTClient_cycle(&sock, 100L, rc); if (sock == m->c->net.socket) { if (*rc == SOCKET_ERROR) break; if (pack && (pack->header.bits.type == packet_type)) break; if (m->c->connect_state == 1) { int error; socklen_t len = sizeof(error); if ((*rc = getsockopt(m->c->net.socket, SOL_SOCKET, SO_ERROR, (char*)&error, &len)) == 0) *rc = error; break; } #if defined(OPENSSL) else if (m->c->connect_state == 2) { *rc = SSLSocket_connect(m->c->net.ssl, sock); if (*rc == SSL_FATAL) break; else if (*rc == 1) /* rc == 1 means SSL connect has finished and succeeded */ { if (!m->c->cleansession && m->c->session == NULL) m->c->session = SSL_get1_session(m->c->net.ssl); break; } } #endif else if (m->c->connect_state == 3) { int error; socklen_t len = sizeof(error); if (getsockopt(m->c->net.socket, SOL_SOCKET, SO_ERROR, (char*)&error, &len) == 0) { if (error) { *rc = error; break; } } } } if (MQTTClient_elapsed(start) > timeout) { pack = NULL; break; } } } exit: FUNC_EXIT_RC(*rc); return pack; }
MQTTPacket* MQTTClient_waitfor(MQTTClient handle, int packet_type, int* rc, long timeout) { MQTTPacket* pack = NULL; MQTTClients* m = handle; START_TIME_TYPE start = MQTTClient_start_clock(); FUNC_ENTRY; if (((MQTTClients*)handle) == NULL) { *rc = MQTTCLIENT_FAILURE; goto exit; } if (running) { if (packet_type == CONNECT) { if ((*rc = Thread_wait_sem(m->connect_sem)) == 0) *rc = m->rc; } else if (packet_type == CONNACK) *rc = Thread_wait_sem(m->connack_sem); else if (packet_type == SUBACK) *rc = Thread_wait_sem(m->suback_sem); else if (packet_type == UNSUBACK) *rc = Thread_wait_sem(m->unsuback_sem); if (*rc == 0 && packet_type != CONNECT && m->pack == NULL) Log(TRACE_MIN, -1, "waitfor unexpectedly is NULL for client %s, packet_type %d", m->c->clientID, packet_type); pack = m->pack; } else { *rc = TCPSOCKET_COMPLETE; while (1) { int sock = -1; pack = MQTTClient_cycle(&sock, 100L, rc); if (sock == m->c->socket) { if (pack && (pack->header.bits.type == packet_type)) break; if (m->c->connect_state == 1) { int error; socklen_t len = sizeof(error); if ((*rc = getsockopt(m->c->socket, SOL_SOCKET, SO_ERROR, (char*)&error, &len)) == 0) *rc = error; break; } } else if (MQTTClient_elapsed(start) > timeout) { pack = NULL; break; } } } exit: FUNC_EXIT_RC(*rc); return pack; }