@ -21,6 +21,7 @@ Contributors:
# include <assert.h>
# ifndef WIN32
# include <poll.h>
# include <unistd.h>
# else
# include <process.h>
# include <winsock2.h>
@ -106,13 +107,12 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
# endif
int i ;
struct pollfd * pollfds = NULL ;
int pollfd_count = 0 ;
int pollfd_index ;
int pollfd_max ;
# ifdef WITH_BRIDGE
mosq_sock_t bridge_sock ;
int rc ;
# endif
int context_count ;
time_t expiration_check_time = 0 ;
time_t last_timeout_check = 0 ;
char * id ;
@ -120,8 +120,22 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
# ifndef WIN32
sigemptyset ( & sigblock ) ;
sigaddset ( & sigblock , SIGINT ) ;
sigaddset ( & sigblock , SIGTERM ) ;
sigaddset ( & sigblock , SIGHUP ) ;
# endif
# ifdef WIN32
pollfd_max = _getmaxstdio ( ) ;
# else
pollfd_max = sysconf ( _SC_OPEN_MAX ) ;
# endif
pollfds = _mosquitto_malloc ( sizeof ( struct pollfd ) * pollfd_max ) ;
if ( ! pollfds ) {
_mosquitto_log_printf ( NULL , MOSQ_LOG_ERR , " Error: Out of memory. " ) ;
return MOSQ_ERR_NOMEM ;
}
if ( db - > config - > persistent_client_expiration > 0 ) {
expiration_check_time = time ( NULL ) + 3600 ;
}
@ -134,21 +148,7 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
}
# endif
context_count = HASH_CNT ( hh_sock , db - > contexts_by_sock ) ;
# ifdef WITH_BRIDGE
context_count + = db - > bridge_count ;
# endif
if ( listensock_count + context_count > pollfd_count | | ! pollfds ) {
pollfd_count = listensock_count + 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 ) ;
memset ( pollfds , - 1 , sizeof ( struct pollfd ) * pollfd_max ) ;
pollfd_index = 0 ;
for ( i = 0 ; i < listensock_count ; i + + ) {
@ -196,8 +196,9 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
pollfds [ pollfd_index ] . fd = context - > sock ;
pollfds [ pollfd_index ] . events = POLLIN ;
pollfds [ pollfd_index ] . revents = 0 ;
if ( context - > current_out_packet | | context - > state = = mosq_cs_connect_pending ) {
if ( context - > current_out_packet | | context - > state = = mosq_cs_connect_pending | | context - > ws_want_write ) {
pollfds [ pollfd_index ] . events | = POLLOUT ;
context - > ws_want_write = false ;
}
context - > pollfd_index = pollfd_index ;
pollfd_index + + ;
@ -436,7 +437,11 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context)
if ( context - > wsi ) {
libwebsocket_callback_on_writable ( context - > ws_context , context - > wsi ) ;
}
context - > sock = INVALID_SOCKET ;
if ( context - > sock ! = INVALID_SOCKET ) {
HASH_DELETE ( hh_sock , db - > contexts_by_sock , context ) ;
context - > sock = INVALID_SOCKET ;
context - > pollfd_index = - 1 ;
}
} else
# endif
{
@ -482,6 +487,18 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol
}
assert ( pollfds [ context - > pollfd_index ] . fd = = context - > sock ) ;
# ifdef WITH_WEBSOCKETS
if ( context - > wsi ) {
struct lws_pollfd wspoll ;
wspoll . fd = pollfds [ context - > pollfd_index ] . fd ;
wspoll . events = pollfds [ context - > pollfd_index ] . events ;
wspoll . revents = pollfds [ context - > pollfd_index ] . revents ;
lws_service_fd ( lws_get_context ( context - > wsi ) , & wspoll ) ;
continue ;
}
# endif
# ifdef WITH_TLS
if ( pollfds [ context - > pollfd_index ] . revents & POLLOUT | |
context - > want_write | |
@ -511,6 +528,12 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol
if ( context - > pollfd_index < 0 ) {
continue ;
}
# ifdef WITH_WEBSOCKETS
if ( context - > wsi ) {
// Websocket are already handled above
continue ;
}
# endif
# ifdef WITH_TLS
if ( pollfds [ context - > pollfd_index ] . revents & POLLIN | |
@ -525,7 +548,7 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol
}
} while ( SSL_DATA_PENDING ( context ) ) ;
}
if ( pollfds[ context - > pollfd_index ] . revents & ( POLLERR | POLLNVAL | POLLHUP ) ) {
if ( context- > pollfd_index > = 0 & & pollfds[ context - > pollfd_index ] . revents & ( POLLERR | POLLNVAL | POLLHUP ) ) {
do_disconnect ( db , context ) ;
continue ;
}