summaryrefslogtreecommitdiffstats
path: root/include/internal/event_queue.h
blob: 3b1ba50741bdf5aba2471f1d81a830e194d7dc3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#ifndef OSSL_INTERNAL_EVENT_QUEUE_H
# define OSSL_INTERNAL_EVENT_QUEUE_H
# pragma once

# include "internal/priority_queue.h"
# include "internal/time.h"

/*
 * Opaque type holding an event.
 */
typedef struct ossl_event_st OSSL_EVENT;

DEFINE_PRIORITY_QUEUE_OF(OSSL_EVENT);

/*
 * Public type representing an event queue, the underlying structure being
 * opaque.
 */
typedef struct ossl_event_queue_st OSSL_EVENT_QUEUE;

/*
 * Public type representing a event queue entry.
 * It is (internally) public so that it can be embedded into other structures,
 * it should otherwise be treated as opaque.
 */
struct ossl_event_st {
    uint32_t type;              /* What type of event this is               */
    uint32_t priority;          /* What priority this event has             */
    OSSL_TIME when;             /* When the event is scheduled to happen    */
    void *ctx;                  /* User argument passed to call backs       */
    void *payload;              /* Event specific data of unknown kind      */
    size_t payload_size;        /* Length (in bytes) of event specific data */

    /* These fields are for internal use only */
    PRIORITY_QUEUE_OF(OSSL_EVENT) *queue;    /* Queue containing this event */
    size_t ref;                 /* ID for this event                        */
    unsigned int flag_dynamic : 1;  /* Malloced or not?                     */
};

/*
 * Utility function to populate an event structure and add it to the queue
 */
int ossl_event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event,
                         uint32_t type, uint32_t priority,
                         OSSL_TIME when, void *ctx,
                         void *payload, size_t payload_size);

/*
 * Utility functions to extract event fields
 */
static ossl_unused ossl_inline
uint32_t ossl_event_get_type(const OSSL_EVENT *event)
{
    return event->type;
}

static ossl_unused ossl_inline
uint32_t ossl_event_get_priority(const OSSL_EVENT *event)
{
    return event->priority;
}

static ossl_unused ossl_inline
OSSL_TIME ossl_event_get_when(const OSSL_EVENT *event)
{
    return event->when;
}

static ossl_unused ossl_inline
void *ossl_event_get0_ctx(const OSSL_EVENT *event)
{
    return event->ctx;
}

static ossl_unused ossl_inline
void *ossl_event_get0_payload(const OSSL_EVENT *event, size_t *length)
{
    if (length != NULL)
        *length = event->payload_size;
    return event->payload;
}

/*
 * Create and free a queue.
 */
OSSL_EVENT_QUEUE *ossl_event_queue_new(void);
void ossl_event_queue_free(OSSL_EVENT_QUEUE *queue);

/*
 * Schedule a new event into an event queue.
 *
 * The event parameters are taken from the function arguments.
 *
 * The function returns NULL on failure and the added event on success.
 */
OSSL_EVENT *ossl_event_queue_add_new(OSSL_EVENT_QUEUE *queue,
                                     uint32_t type, uint32_t priority,
                                     OSSL_TIME when, void *ctx,
                                     void *payload, size_t payload_size)
;

/*
 * Schedule an event into an event queue.
 *
 * The event parameters are taken from the function arguments.
 *
 * The function returns 0 on failure and 1 on success.
 */
int ossl_event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event,
                         uint32_t type, uint32_t priority,
                         OSSL_TIME when, void *ctx,
                         void *payload, size_t payload_size);

/*
 * Delete an event from the queue.
 * This will cause the early deletion function to be called if it is non-NULL.
 * A pointer to the event structure is returned.
 */
int ossl_event_queue_remove(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event);

/*
 * Free a dynamic event.
 * Is a NOP for a static event.
 */
void ossl_event_free(OSSL_EVENT *event);

/*
 * Return the time until the next event for the specified event, if the event's
 * time is past, zero is returned.  Once activated, the event reference becomes
 * invalid and this function becomes undefined.
 */
OSSL_TIME ossl_event_time_until(const OSSL_EVENT *event);

/*
 * Return the time until the next event in the queue.
 * If the next event is in the past, zero is returned.
 */
OSSL_TIME ossl_event_queue_time_until_next(const OSSL_EVENT_QUEUE *queue);

/*
 * Postpone an event to trigger at the specified time.
 * If the event has triggered, this function's behaviour is undefined.
 */
int ossl_event_queue_postpone_until(OSSL_EVENT_QUEUE *queue,
                                    OSSL_EVENT *event,
                                    OSSL_TIME when);

/*
 * Return the next event to process.
 */
int ossl_event_queue_get1_next_event(OSSL_EVENT_QUEUE *queue,
                                     OSSL_EVENT **event);

#endif