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