Ejemplo n.º 1
0
int mosquitto_main_loop(struct mosquitto_db *db, int *listensock, int listensock_count, int listener_max)
{
    time_t start_time = time(NULL);
    time_t last_backup = time(NULL);
    time_t last_store_clean = time(NULL);
    time_t now;

    sigset_t sigblock, origsig;

    int i, s;  /* temp variables */
    struct epoll_event* events = NULL;
    int epollfd_count = 0;
    int epollfd_index;
    int efd;  /* epoll fd */



    while (run) {

    mqtt3_db_sys_update(db, db->config->sys_interval, start_time);
    events = init_events(events, listensock_count, db->context_count, &epollfd_count);

    if (!events) {
        _mosquitto_log_printf (NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
        return MOSQ_ERR_NOMEM;
    }

    memset(events, -1, sizeof(struct epoll_event) * epollfd_count);

    epollfd_index = 0;
    efd = create_event(events, listensock, listensock_count, &epollfd_index);

    now = time (NULL);
    reg_context_events(db, events, &epollfd_index, efd, now);


        mqtt3_db_message_timeout_check(db, db->config->retry_interval);

        sigprocmask(SIG_SETMASK, &sigblock, &origsig);

        s = epoll_wait(efd, events, 64, -1);

        if (s == -1) {
            printf("errno value: %d, it means: %s", errno, strerror(errno));
            loop_handle_errors(db, events, efd);
        }

        if (s == -1) {
            printf("errno value: %d, it means: %s", errno, strerror(errno));
            loop_handle_errors(db, events, efd);
        } else{
            loop_handle_reads_writes(db, events, efd);

            for(i=0; i<listensock_count; i++){
                if(events[i].events & (EPOLLIN | EPOLLPRI)){
                    while((s = mqtt3_socket_accept(db, listensock[i], &events[i], efd)) != -1){

                    }
                }
            }
        }

        sigprocmask(SIG_SETMASK, &origsig, NULL);

#ifdef WITH_PERSISTENCE
        if(db->config->persistence && db->config->autosave_interval){
            if(db->config->autosave_on_changes){
                if(db->persistence_changes > db->config->autosave_interval){
                    mqtt3_db_backup(db, false, false);
                    db->persistence_changes = 0;
                }
            }else{
                if(last_backup + db->config->autosave_interval < now){
                    mqtt3_db_backup(db, false, false);
                    last_backup = time(NULL);
                }
            }
        }
#endif
        if(!db->config->store_clean_interval || last_store_clean + db->config->store_clean_interval < now){
            mqtt3_db_store_clean(db);
            last_store_clean = time(NULL);
        }
#ifdef WITH_PERSISTENCE
        if(flag_db_backup){
            mqtt3_db_backup(db, false, false);
            flag_db_backup = false;
        }
#endif
        if(flag_reload){
            _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Reloading config.");
            mqtt3_config_read(db->config, true);
            mosquitto_security_cleanup(db, true);
            mosquitto_security_init(db, true);
            mosquitto_security_apply(db);
            mqtt3_log_init(db->config->log_type, db->config->log_dest);
            flag_reload = false;
        }
        if(flag_tree_print){
            mqtt3_sub_tree_print(&db->subs, 0);
            flag_tree_print = false;
        }
    }

    if(events) _mosquitto_free(events);
    return MOSQ_ERR_SUCCESS;
}
Ejemplo n.º 2
0
int mosquitto_main_loop(struct mosquitto_db *db, int *listensock, int listensock_count, int listener_max)
{
	time_t start_time = time(NULL);
	time_t last_backup = time(NULL);
	time_t last_store_clean = time(NULL);
	time_t now;
	int fdcount;
#ifndef WIN32
	sigset_t sigblock, origsig;
#endif
	int i;
	struct pollfd *pollfds = NULL;
	int pollfd_count = 0;
	int pollfd_index;

#ifndef WIN32
	sigemptyset(&sigblock);
	sigaddset(&sigblock, SIGINT);
#endif

	while(run){
		mqtt3_db_sys_update(db, db->config->sys_interval, start_time);

		if(listensock_count + db->context_count > pollfd_count){
			pollfd_count = listensock_count + db->context_count;
			pollfds = _mosquitto_realloc(pollfds, sizeof(struct pollfd)*pollfd_count);
			if(!pollfds){
				_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
				return MOSQ_ERR_NOMEM;
			}
		}

		memset(pollfds, -1, sizeof(struct pollfd)*pollfd_count);

		pollfd_index = 0;
		for(i=0; i<listensock_count; i++){
			pollfds[pollfd_index].fd = listensock[i];
			pollfds[pollfd_index].events = POLLIN;
			pollfds[pollfd_index].revents = 0;
			pollfd_index++;
		}

		now = time(NULL);
		for(i=0; i<db->context_count; i++){
			if(db->contexts[i]){
				db->contexts[i]->pollfd_index = -1;

				if(db->contexts[i]->sock != INVALID_SOCKET){
#ifdef WITH_BRIDGE
					if(db->contexts[i]->bridge){
						_mosquitto_check_keepalive(db->contexts[i]);
					}
#endif

					/* Local bridges never time out in this fashion. */
					if(!(db->contexts[i]->keepalive) || db->contexts[i]->bridge || now - db->contexts[i]->last_msg_in < (time_t)(db->contexts[i]->keepalive)*3/2){
						if(mqtt3_db_message_write(db->contexts[i]) == MOSQ_ERR_SUCCESS){
							pollfds[pollfd_index].fd = db->contexts[i]->sock;
							pollfds[pollfd_index].events = POLLIN | POLLRDHUP;
							pollfds[pollfd_index].revents = 0;
							if(db->contexts[i]->out_packet){
								pollfds[pollfd_index].events |= POLLOUT;
							}
							db->contexts[i]->pollfd_index = pollfd_index;
							pollfd_index++;
						}else{
							mqtt3_context_disconnect(db, db->contexts[i]);
						}
					}else{
						if(db->config->connection_messages == true){
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", db->contexts[i]->id);
						}
						/* Client has exceeded keepalive*1.5 */
						mqtt3_context_disconnect(db, db->contexts[i]);
					}
				}else{
#ifdef WITH_BRIDGE
					if(db->contexts[i]->bridge){
						/* Want to try to restart the bridge connection */
						if(!db->contexts[i]->bridge->restart_t){
							db->contexts[i]->bridge->restart_t = time(NULL)+db->contexts[i]->bridge->restart_timeout;
						}else{
							if(db->contexts[i]->bridge->start_type == bst_automatic && time(NULL) > db->contexts[i]->bridge->restart_t){
								db->contexts[i]->bridge->restart_t = 0;
								if(mqtt3_bridge_connect(db, db->contexts[i]) == MOSQ_ERR_SUCCESS){
									pollfds[pollfd_index].fd = db->contexts[i]->sock;
									pollfds[pollfd_index].events = POLLIN | POLLRDHUP;
									pollfds[pollfd_index].revents = 0;
									if(db->contexts[i]->out_packet){
										pollfds[pollfd_index].events |= POLLOUT;
									}
									db->contexts[i]->pollfd_index = pollfd_index;
									pollfd_index++;
								}else{
									/* Retry later. */
									db->contexts[i]->bridge->restart_t = time(NULL)+db->contexts[i]->bridge->restart_timeout;
								}
							}
						}
					}else{
#endif
						if(db->contexts[i]->clean_session == true){
							mqtt3_context_cleanup(db, db->contexts[i], true);
							db->contexts[i] = NULL;
						}else if(db->config->persistent_client_expiration > 0){
							/* This is a persistent client, check to see if the
							 * last time it connected was longer than
							 * persistent_client_expiration seconds ago. If so,
							 * expire it and clean up.
							 */
							if(time(NULL) > db->contexts[i]->disconnect_t+db->config->persistent_client_expiration){
								_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Expiring persistent client %s due to timeout.", db->contexts[i]->id);
								g_clients_expired++;
								db->contexts[i]->clean_session = true;
								mqtt3_context_cleanup(db, db->contexts[i], true);
								db->contexts[i] = NULL;
							}
						}
#ifdef WITH_BRIDGE
					}
#endif
				}
			}
		}

		mqtt3_db_message_timeout_check(db, db->config->retry_interval);

#ifndef WIN32
		sigprocmask(SIG_SETMASK, &sigblock, &origsig);
		fdcount = poll(pollfds, pollfd_index, 100);
		sigprocmask(SIG_SETMASK, &origsig, NULL);
#else
		fdcount = WSAPoll(pollfds, pollfd_index, 100);
#endif
		if(fdcount == -1){
			loop_handle_errors(db, pollfds);
		}else{
			loop_handle_reads_writes(db, pollfds);

			for(i=0; i<listensock_count; i++){
				if(pollfds[i].revents & (POLLIN | POLLPRI)){
					while(mqtt3_socket_accept(db, listensock[i]) != -1){
					}
				}
			}
		}
#ifdef WITH_PERSISTENCE
		if(db->config->persistence && db->config->autosave_interval){
			if(db->config->autosave_on_changes){
				if(db->persistence_changes > db->config->autosave_interval){
					mqtt3_db_backup(db, false, false);
					db->persistence_changes = 0;
				}
			}else{
				if(last_backup + db->config->autosave_interval < now){
					mqtt3_db_backup(db, false, false);
					last_backup = time(NULL);
				}
			}
		}
#endif
		if(!db->config->store_clean_interval || last_store_clean + db->config->store_clean_interval < now){
			mqtt3_db_store_clean(db);
			last_store_clean = time(NULL);
		}
#ifdef WITH_PERSISTENCE
		if(flag_db_backup){
			mqtt3_db_backup(db, false, false);
			flag_db_backup = false;
		}
#endif
		if(flag_reload){
			_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Reloading config.");
			mqtt3_config_read(db->config, true);
			mosquitto_security_cleanup(db, true);
			mosquitto_security_init(db, true);
			mosquitto_security_apply(db);
			mqtt3_log_init(db->config->log_type, db->config->log_dest);
			flag_reload = false;
		}
		if(flag_tree_print){
			mqtt3_sub_tree_print(&db->subs, 0);
			flag_tree_print = false;
		}
	}

	if(pollfds) _mosquitto_free(pollfds);
	return MOSQ_ERR_SUCCESS;
}