| 282 | { |
| 283 | #if defined(MBEDTLS_THREADING_ALT) |
| 284 | MbedTlsThreading() |
| 285 | { |
| 286 | mbedtls_threading_set_alt( |
| 287 | [](mbedtls_threading_mutex_t* ptr) // Construction |
| 288 | { |
| 289 | if (!ptr) |
| 290 | return; |
| 291 | *ptr = std::make_unique<std::mutex>().release(); |
| 292 | }, |
| 293 | [](mbedtls_threading_mutex_t* ptr) // Destruction |
| 294 | { |
| 295 | if (!ptr) |
| 296 | return; |
| 297 | [[maybe_unused]] const std::unique_ptr<std::mutex> dummy(static_cast<std::mutex*>(*ptr)); |
| 298 | }, |
| 299 | [](mbedtls_threading_mutex_t* ptr) // Lock |
| 300 | { |
| 301 | if (!ptr) |
| 302 | return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; |
| 303 | try |
| 304 | { |
| 305 | static_cast<std::mutex*>(*ptr)->lock(); |
| 306 | } catch (const std::exception&) |
| 307 | { |
| 308 | return MBEDTLS_ERR_THREADING_MUTEX_ERROR; |
| 309 | } |
| 310 | return 0; |
| 311 | }, |
| 312 | [](mbedtls_threading_mutex_t* ptr) // Unlock |
| 313 | { |
| 314 | if (!ptr) |
| 315 | return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; |
| 316 | try |
| 317 | { |
| 318 | #ifdef _MSC_VER |
| 319 | #pragma warning(push) |
| 320 | #pragma warning(disable : 26110) // Caller failing to hold lock before calling function |
| 321 | #endif |
| 322 | static_cast<std::mutex*>(*ptr)->unlock(); |
| 323 | #ifdef _MSC_VER |
| 324 | #pragma warning(pop) |
| 325 | #endif |
| 326 | } catch (const std::exception&) |
| 327 | { |
| 328 | return MBEDTLS_ERR_THREADING_MUTEX_ERROR; |
| 329 | } |
| 330 | return 0; |
| 331 | }); |
| 332 | } |
| 333 | |
| 334 | ~MbedTlsThreading() |
| 335 | { |