Home | History | Annotate | Line # | Download | only in quic
      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 
     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 
     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 
     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 
     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 
     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 
     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     {
     83         assert(slot->blocking_count == 0);
     84         OPENSSL_free(slot);
     85     }
     86 }
     87