int main(int argc, char *argv[]) { int rc = 0; sem_type sem = Thread_create_sem(); printf("check sem %d\n", Thread_check_sem(sem)); printf("post secondary\n"); rc = Thread_post_sem(sem); printf("posted secondary %d\n", rc); printf("check sem %d\n", Thread_check_sem(sem)); printf("Starting secondary thread\n"); Thread_start(secondary, (void*)sem); sleep(3); printf("check sem %d\n", Thread_check_sem(sem)); printf("post secondary\n"); rc = Thread_post_sem(sem); printf("posted secondary %d\n", rc); sleep(3); printf("Main thread ending\n"); }
int MQTTClient_disconnect1(MQTTClient handle, int timeout, int internal) { 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); } } MQTTProtocol_closeSession(m->c, 0); if (Thread_check_sem(m->connect_sem)) Thread_post_sem(m->connect_sem); if (Thread_check_sem(m->connack_sem)) Thread_post_sem(m->connack_sem); if (Thread_check_sem(m->suback_sem)) Thread_post_sem(m->suback_sem); if (Thread_check_sem(m->unsuback_sem)) Thread_post_sem(m->unsuback_sem); exit: 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; }
/* This is the thread function that handles the calling of callback functions if set */ thread_return_type WINAPI MQTTClient_run(void* n) { long timeout = 10L; /* first time in we have a small timeout. Gets things started more quickly */ FUNC_ENTRY; running = 1; run_id = Thread_getid(); Thread_lock_mutex(mqttclient_mutex); while (!tostop) { int rc = SOCKET_ERROR; int sock = -1; MQTTClients* m = NULL; MQTTPacket* pack = NULL; Thread_unlock_mutex(mqttclient_mutex); pack = MQTTClient_cycle(&sock, timeout, &rc); Thread_lock_mutex(mqttclient_mutex); if (tostop) break; timeout = 1000L; /* find client corresponding to socket */ if (ListFindItem(handles, &sock, clientSockCompare) == NULL) { /* assert: should not happen */ continue; } m = (MQTTClient)(handles->current->content); if (m == NULL) { /* assert: should not happen */ continue; } if (rc == SOCKET_ERROR) { if (m->c->connected) { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_disconnect_internal(m, 0); Thread_lock_mutex(mqttclient_mutex); } else { if (m->c->connect_state == 2 && !Thread_check_sem(m->connect_sem)) { Log(TRACE_MIN, -1, "Posting connect semaphore for client %s", m->c->clientID); Thread_post_sem(m->connect_sem); } if (m->c->connect_state == 3 && !Thread_check_sem(m->connack_sem)) { Log(TRACE_MIN, -1, "Posting connack semaphore for client %s", m->c->clientID); Thread_post_sem(m->connack_sem); } } } else { if (m->c->messageQueue->count > 0) { qEntry* qe = (qEntry*)(m->c->messageQueue->first->content); int topicLen = qe->topicLen; if (strlen(qe->topicName) == topicLen) topicLen = 0; Log(TRACE_MIN, -1, "Calling messageArrived for client %s, queue depth %d", m->c->clientID, m->c->messageQueue->count); Thread_unlock_mutex(mqttclient_mutex); rc = (*(m->ma))(m->context, qe->topicName, topicLen, qe->msg); Thread_lock_mutex(mqttclient_mutex); /* if 0 (false) is returned by the callback then it failed, so we don't remove the message from * the queue, and it will be retried later. If 1 is returned then the message data may have been freed, * so we must be careful how we use it. */ if (rc) ListRemove(m->c->messageQueue, qe); else Log(TRACE_MIN, -1, "False returned from messageArrived for client %s, message remains on queue", m->c->clientID); } if (pack) { if (pack->header.bits.type == CONNACK && !Thread_check_sem(m->connack_sem)) { Log(TRACE_MIN, -1, "Posting connack semaphore for client %s", m->c->clientID); m->pack = pack; Thread_post_sem(m->connack_sem); } else if (pack->header.bits.type == SUBACK) { Log(TRACE_MIN, -1, "Posting suback semaphore for client %s", m->c->clientID); m->pack = pack; Thread_post_sem(m->suback_sem); } else if (pack->header.bits.type == UNSUBACK) { Log(TRACE_MIN, -1, "Posting unsuback semaphore for client %s", m->c->clientID); m->pack = pack; Thread_post_sem(m->unsuback_sem); } } else if (m->c->connect_state == 1 && !Thread_check_sem(m->connect_sem)) { int error; socklen_t len = sizeof(error); if ((m->rc = getsockopt(m->c->net.socket, SOL_SOCKET, SO_ERROR, (char*)&error, &len)) == 0) m->rc = error; Log(TRACE_MIN, -1, "Posting connect semaphore for client %s rc %d", m->c->clientID, m->rc); Thread_post_sem(m->connect_sem); } #if defined(OPENSSL) else if (m->c->connect_state == 2 && !Thread_check_sem(m->connect_sem)) { rc = SSLSocket_connect(m->c->net.ssl, m->c->net.socket); if (rc == 1 || rc == SSL_FATAL) { if (rc == 1 && !m->c->cleansession && m->c->session == NULL) m->c->session = SSL_get1_session(m->c->net.ssl); m->rc = rc; Log(TRACE_MIN, -1, "Posting connect semaphore for SSL client %s rc %d", m->c->clientID, m->rc); Thread_post_sem(m->connect_sem); } } #endif } } run_id = 0; running = tostop = 0; Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT; return 0; }