#include "urldata.h"
#include "api.h"
+#include "curl_threads.h"
#include "multiif.h"
+#include "vtls/vtls_scache.h"
struct Curl_eapi_fn_props {
Curl_eapi_fn fn;
uint8_t data_is_killed; /* easy handle is killed in call */
uint8_t recurse; /* may be called when another call is in progress */
uint8_t no_event_cb; /* may not be called during a multi event callback */
+ uint8_t no_scache_lock; /* may not be called with easy's vtls_scache
+ locked by current thread */
};
static const struct Curl_eapi_fn_props eapi_fn_props[CURL_EAPI_FN_LAST] = {
- /* function kill rec !ev */
- { CURL_EAPI_FN_easy_cleanup, 1, 0, 0 },
- { CURL_EAPI_FN_easy_duphandle, 0, 1, 0 },
- { CURL_EAPI_FN_easy_getinfo, 0, 1, 0 },
- { CURL_EAPI_FN_easy_pause, 0, 1, 1 },
- { CURL_EAPI_FN_easy_perform_ev, 0, 0, 0 },
- { CURL_EAPI_FN_easy_perform, 0, 0, 0 },
- { CURL_EAPI_FN_easy_recv, 0, 0, 0 },
- { CURL_EAPI_FN_easy_reset, 0, 0, 0 },
- { CURL_EAPI_FN_easy_send, 0, 0, 0 },
- { CURL_EAPI_FN_easy_setopt, 0, 1, 0 },
- { CURL_EAPI_FN_easy_ssls_export, 0, 0, 0 },
- { CURL_EAPI_FN_easy_ssls_import, 0, 0, 0 },
- { CURL_EAPI_FN_easy_upkeep, 0, 0, 0 },
- { CURL_EAPI_FN_ws_recv, 0, 1, 0 },
- { CURL_EAPI_FN_ws_send, 0, 1, 0 },
- { CURL_EAPI_FN_ws_start_frame, 0, 1, 0 },
+ /* function kill rec !ev !scach */
+ { CURL_EAPI_FN_easy_cleanup, 1, 0, 0, 0 },
+ { CURL_EAPI_FN_easy_duphandle, 0, 1, 0, 0 },
+ { CURL_EAPI_FN_easy_getinfo, 0, 1, 0, 0 },
+ { CURL_EAPI_FN_easy_pause, 0, 1, 1, 0 },
+ { CURL_EAPI_FN_easy_perform_ev, 0, 0, 0, 1 },
+ { CURL_EAPI_FN_easy_perform, 0, 0, 0, 1 },
+ { CURL_EAPI_FN_easy_recv, 0, 0, 0, 1 },
+ { CURL_EAPI_FN_easy_reset, 0, 0, 0, 0 },
+ { CURL_EAPI_FN_easy_send, 0, 0, 0, 1 },
+ { CURL_EAPI_FN_easy_setopt, 0, 1, 0, 0 },
+ { CURL_EAPI_FN_easy_ssls_export, 0, 0, 0, 1 },
+ { CURL_EAPI_FN_easy_ssls_import, 0, 0, 0, 1 },
+ { CURL_EAPI_FN_easy_upkeep, 0, 0, 0, 1 },
+ { CURL_EAPI_FN_ws_recv, 0, 1, 0, 1 },
+ { CURL_EAPI_FN_ws_send, 0, 1, 0, 1 },
+ { CURL_EAPI_FN_ws_start_frame, 0, 1, 0, 0 },
};
struct Curl_mapi_fn_props {
uint8_t multi_is_killed; /* multi handle is killed during call */
uint8_t recurse; /* may be called when another call is in progress */
uint8_t allow_ntfy_cb; /* may be called during a notify callback */
+ uint8_t no_scache_lock; /* may not be called with multi's vtls_scache
+ locked by current thread */
};
static const struct Curl_mapi_fn_props mapi_fn_props[CURL_MAPI_FN_LAST] = {
- /* function kill rec ntfy */
- { CURL_MAPI_FN_multi_add_handle, 0, 0, 1 },
- { CURL_MAPI_FN_multi_assign, 0, 1, 1 },
- { CURL_MAPI_FN_multi_cleanup, 1, 0, 0 },
- { CURL_MAPI_FN_multi_fdset, 0, 0, 1 },
- { CURL_MAPI_FN_multi_get_handles, 0, 1, 1 },
- { CURL_MAPI_FN_multi_get_offt, 0, 1, 1 },
- { CURL_MAPI_FN_multi_info_read, 0, 1, 1 },
- { CURL_MAPI_FN_multi_notify_disable, 0, 1, 1 },
- { CURL_MAPI_FN_multi_notify_enable, 0, 1, 1 },
- { CURL_MAPI_FN_multi_perform, 0, 0, 0 },
- { CURL_MAPI_FN_multi_poll, 0, 0, 1 },
- { CURL_MAPI_FN_multi_remove_handle, 0, 0, 1 },
- { CURL_MAPI_FN_multi_setopt, 0, 0, 1 },
- { CURL_MAPI_FN_multi_socket_action, 0, 0, 0 },
- { CURL_MAPI_FN_multi_socket_all, 0, 0, 0 },
- { CURL_MAPI_FN_multi_socket, 0, 0, 0 },
- { CURL_MAPI_FN_multi_timeout, 0, 0, 1 },
- { CURL_MAPI_FN_multi_wait, 0, 0, 1 },
- { CURL_MAPI_FN_multi_waitfds, 0, 0, 1 },
+ /* function kill rec ntfy !scach */
+ { CURL_MAPI_FN_multi_add_handle, 0, 0, 1, 0 },
+ { CURL_MAPI_FN_multi_assign, 0, 1, 1, 0 },
+ { CURL_MAPI_FN_multi_cleanup, 1, 0, 0, 1 },
+ { CURL_MAPI_FN_multi_fdset, 0, 0, 1, 0 },
+ { CURL_MAPI_FN_multi_get_handles, 0, 1, 1, 0 },
+ { CURL_MAPI_FN_multi_get_offt, 0, 1, 1, 0 },
+ { CURL_MAPI_FN_multi_info_read, 0, 1, 1, 0 },
+ { CURL_MAPI_FN_multi_notify_disable, 0, 1, 1, 0 },
+ { CURL_MAPI_FN_multi_notify_enable, 0, 1, 1, 0 },
+ { CURL_MAPI_FN_multi_perform, 0, 0, 0, 1 },
+ { CURL_MAPI_FN_multi_poll, 0, 0, 1, 0 },
+ { CURL_MAPI_FN_multi_remove_handle, 0, 0, 1, 0 },
+ { CURL_MAPI_FN_multi_setopt, 0, 0, 1, 0 },
+ { CURL_MAPI_FN_multi_socket_action, 0, 0, 0, 1 },
+ { CURL_MAPI_FN_multi_socket_all, 0, 0, 0, 1 },
+ { CURL_MAPI_FN_multi_socket, 0, 0, 0, 1 },
+ { CURL_MAPI_FN_multi_timeout, 0, 0, 1, 1 },
+ { CURL_MAPI_FN_multi_wait, 0, 0, 1, 0 },
+ { CURL_MAPI_FN_multi_waitfds, 0, 0, 1, 0 },
};
struct Curl_cbapi_fn_props {
goto out;
}
+#if defined(USE_SSL) && defined(USE_MUTEX)
+ if(fn_props->no_scache_lock &&
+ Curl_ssl_scache_is_locked_by_current_thread(data)) {
+#ifdef CURLVERBOSE
+ DEBUGF(curl_mfprintf(stderr,
+ "EAPI guard: calling %u while vtls_scache is locked by "
+ "current thread\n", (uint16_t)fn));
+#endif
+ result = CURLE_RECURSIVE_API_CALL;
+ goto out;
+ }
+#endif
+
/* all fine, add to data's callstack */
if(data->callstack.count >= CURL_EAPI_MAX_RECURSION) {
result = CURLE_RECURSIVE_API_CALL;
goto out;
}
+#if defined(USE_SSL) && defined(USE_MUTEX)
+ if(fn_props->no_scache_lock && multi->ssl_scache &&
+ Curl_ssl_scache_is_locked_by_current_thread(multi->admin)) {
+#ifdef CURLVERBOSE
+ DEBUGF(curl_mfprintf(stderr,
+ "MAPI guard: calling %u while its vtls_scache is locked by "
+ "current thread\n", (uint16_t)fn));
+#endif
+ mresult = CURLM_RECURSIVE_API_CALL;
+ goto out;
+ }
+#endif
+
/* all fine, add to data's callstack */
if(multi->callstack.count >= CURL_MAPI_MAX_RECURSION) {
mresult = CURLM_RECURSIVE_API_CALL;