xref: /freebsd/crypto/openssl/ssl/quic/quic_reactor_wait_ctx.c (revision e7be843b4a162e68651d3911f0357ed464915629)
1 /*
2  * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 #include "internal/quic_reactor_wait_ctx.h"
10 #include "internal/common.h"
11 #include "internal/thread_arch.h"
12 #include <assert.h>
13 
14 struct quic_reactor_wait_slot_st {
15     OSSL_LIST_MEMBER(quic_reactor_wait_slot, QUIC_REACTOR_WAIT_SLOT);
16     QUIC_REACTOR            *rtor;              /* primary key */
17     size_t                  blocking_count;     /* datum */
18 };
19 
20 DEFINE_LIST_OF_IMPL(quic_reactor_wait_slot, QUIC_REACTOR_WAIT_SLOT);
21 
ossl_quic_reactor_wait_ctx_init(QUIC_REACTOR_WAIT_CTX * ctx)22 void ossl_quic_reactor_wait_ctx_init(QUIC_REACTOR_WAIT_CTX *ctx)
23 {
24     ossl_list_quic_reactor_wait_slot_init(&ctx->slots);
25 }
26 
slot_activate(QUIC_REACTOR_WAIT_SLOT * slot)27 static void slot_activate(QUIC_REACTOR_WAIT_SLOT *slot)
28 {
29     if (++slot->blocking_count == 1)
30         ossl_quic_reactor_enter_blocking_section(slot->rtor);
31 }
32 
slot_deactivate(QUIC_REACTOR_WAIT_SLOT * slot)33 static void slot_deactivate(QUIC_REACTOR_WAIT_SLOT *slot)
34 {
35     assert(slot->blocking_count > 0);
36 
37     if (--slot->blocking_count > 0)
38         return;
39 
40     ossl_quic_reactor_leave_blocking_section(slot->rtor);
41 }
42 
ossl_quic_reactor_wait_ctx_enter(QUIC_REACTOR_WAIT_CTX * ctx,QUIC_REACTOR * rtor)43 int ossl_quic_reactor_wait_ctx_enter(QUIC_REACTOR_WAIT_CTX *ctx,
44                                      QUIC_REACTOR *rtor)
45 {
46     QUIC_REACTOR_WAIT_SLOT *slot;
47 
48     OSSL_LIST_FOREACH(slot, quic_reactor_wait_slot, &ctx->slots)
49         if (slot->rtor == rtor)
50             break;
51 
52     if (slot == NULL) {
53         if ((slot = OPENSSL_zalloc(sizeof(QUIC_REACTOR_WAIT_SLOT))) == NULL)
54             return 0;
55 
56         slot->rtor = rtor;
57         ossl_list_quic_reactor_wait_slot_insert_tail(&ctx->slots, slot);
58     }
59 
60     slot_activate(slot);
61     return 1;
62 }
63 
ossl_quic_reactor_wait_ctx_leave(QUIC_REACTOR_WAIT_CTX * ctx,QUIC_REACTOR * rtor)64 void ossl_quic_reactor_wait_ctx_leave(QUIC_REACTOR_WAIT_CTX *ctx,
65                                       QUIC_REACTOR *rtor)
66 {
67     QUIC_REACTOR_WAIT_SLOT *slot;
68 
69     OSSL_LIST_FOREACH(slot, quic_reactor_wait_slot, &ctx->slots)
70         if (slot->rtor == rtor)
71             break;
72 
73     assert(slot != NULL);
74     slot_deactivate(slot);
75 }
76 
ossl_quic_reactor_wait_ctx_cleanup(QUIC_REACTOR_WAIT_CTX * ctx)77 void ossl_quic_reactor_wait_ctx_cleanup(QUIC_REACTOR_WAIT_CTX *ctx)
78 {
79     QUIC_REACTOR_WAIT_SLOT *slot, *nslot;
80 
81     OSSL_LIST_FOREACH_DELSAFE(slot, nslot, quic_reactor_wait_slot, &ctx->slots) {
82         assert(slot->blocking_count == 0);
83         OPENSSL_free(slot);
84     }
85 }
86