@@ -765,7 +765,14 @@ static bool create_client_data(esp_mqtt_client_handle_t client)
765
765
766
766
esp_mqtt_client_handle_t esp_mqtt_client_init (const esp_mqtt_client_config_t * config )
767
767
{
768
- esp_mqtt_client_handle_t client = calloc (1 , sizeof (struct esp_mqtt_client ));
768
+ esp_mqtt_client_handle_t client = heap_caps_calloc (1 , sizeof (struct esp_mqtt_client ),
769
+ #if MQTT_EVENT_QUEUE_SIZE > 1
770
+ // if supporting multiple queued events, we keep track of them
771
+ // using atomic variable, so need to make sure it won't get allocated in PSRAM
772
+ MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT );
773
+ #else
774
+ MALLOC_CAP_DEFAULT );
775
+ #endif
769
776
ESP_MEM_CHECK (TAG , client , return NULL );
770
777
if (!create_client_data (client )) {
771
778
goto _mqtt_init_failed ;
@@ -776,10 +783,13 @@ esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *co
776
783
}
777
784
#ifdef MQTT_SUPPORTED_FEATURE_EVENT_LOOP
778
785
esp_event_loop_args_t no_task_loop = {
779
- .queue_size = 1 ,
786
+ .queue_size = MQTT_EVENT_QUEUE_SIZE ,
780
787
.task_name = NULL ,
781
788
};
782
789
esp_event_loop_create (& no_task_loop , & client -> config -> event_loop_handle );
790
+ #if MQTT_EVENT_QUEUE_SIZE > 1
791
+ atomic_init (& client -> queued_events , 0 );
792
+ #endif
783
793
#endif
784
794
785
795
client -> keepalive_tick = platform_tick_get_ms ();
@@ -939,6 +949,17 @@ static esp_err_t esp_mqtt_dispatch_event_with_msgid(esp_mqtt_client_handle_t cli
939
949
return esp_mqtt_dispatch_event (client );
940
950
}
941
951
952
+ esp_err_t esp_mqtt_dispatch_custom_event (esp_mqtt_client_handle_t client , esp_mqtt_event_t * event )
953
+ {
954
+ esp_err_t ret = esp_event_post_to (client -> config -> event_loop_handle , MQTT_EVENTS , MQTT_USER_EVENT , event , sizeof (* event ), 0 );
955
+ #if MQTT_EVENT_QUEUE_SIZE > 1
956
+ if (ret == ESP_OK ) {
957
+ atomic_fetch_add (& client -> queued_events , 1 );
958
+ }
959
+ #endif
960
+ return ret ;
961
+ }
962
+
942
963
static esp_err_t esp_mqtt_dispatch_event (esp_mqtt_client_handle_t client )
943
964
{
944
965
client -> event .client = client ;
@@ -1447,6 +1468,34 @@ static void mqtt_delete_expired_messages(esp_mqtt_client_handle_t client)
1447
1468
}
1448
1469
}
1449
1470
1471
+ /**
1472
+ * @brief When using multiple queued item, we'd like to reduce the poll timeout to proceed with event loop exacution
1473
+ */
1474
+ static inline int max_poll_timeout (esp_mqtt_client_handle_t client , int max_timeout )
1475
+ {
1476
+ return
1477
+ #if MQTT_EVENT_QUEUE_SIZE > 1
1478
+ atomic_load (& client -> queued_events ) > 0 ? 10 : max_timeout ;
1479
+ #else
1480
+ max_timeout ;
1481
+ #endif
1482
+ }
1483
+
1484
+ static inline void run_event_loop (esp_mqtt_client_handle_t client )
1485
+ {
1486
+ #if MQTT_EVENT_QUEUE_SIZE > 1
1487
+ if (atomic_load (& client -> queued_events ) > 0 ) {
1488
+ atomic_fetch_sub (& client -> queued_events , 1 );
1489
+ #else
1490
+ {
1491
+ #endif
1492
+ esp_err_t ret = esp_event_loop_run (client -> config -> event_loop_handle , 0 );
1493
+ if (ret != ESP_OK ) {
1494
+ ESP_LOGE (TAG , "Error in running event_loop %d" , ret );
1495
+ }
1496
+ }
1497
+ }
1498
+
1450
1499
static void esp_mqtt_task (void * pv )
1451
1500
{
1452
1501
esp_mqtt_client_handle_t client = (esp_mqtt_client_handle_t ) pv ;
@@ -1470,6 +1519,7 @@ static void esp_mqtt_task(void *pv)
1470
1519
xEventGroupClearBits (client -> status_bits , STOPPED_BIT );
1471
1520
while (client -> run ) {
1472
1521
MQTT_API_LOCK (client );
1522
+ run_event_loop (client );
1473
1523
switch (client -> state ) {
1474
1524
case MQTT_STATE_DISCONNECTED :
1475
1525
break ;
@@ -1571,7 +1621,7 @@ static void esp_mqtt_task(void *pv)
1571
1621
}
1572
1622
MQTT_API_UNLOCK (client );
1573
1623
xEventGroupWaitBits (client -> status_bits , RECONNECT_BIT , false, true,
1574
- client -> wait_timeout_ms / 2 / portTICK_PERIOD_MS );
1624
+ max_poll_timeout ( client , client -> wait_timeout_ms / 2 / portTICK_PERIOD_MS ) );
1575
1625
// continue the while loop instead of break, as the mutex is unlocked
1576
1626
continue ;
1577
1627
default :
@@ -1580,7 +1630,7 @@ static void esp_mqtt_task(void *pv)
1580
1630
}
1581
1631
MQTT_API_UNLOCK (client );
1582
1632
if (MQTT_STATE_CONNECTED == client -> state ) {
1583
- if (esp_transport_poll_read (client -> transport , MQTT_POLL_READ_TIMEOUT_MS ) < 0 ) {
1633
+ if (esp_transport_poll_read (client -> transport , max_poll_timeout ( client , MQTT_POLL_READ_TIMEOUT_MS ) ) < 0 ) {
1584
1634
ESP_LOGE (TAG , "Poll read error: %d, aborting connection" , errno );
1585
1635
esp_mqtt_abort_connection (client );
1586
1636
}
0 commit comments