-
Notifications
You must be signed in to change notification settings - Fork 120
/
az_context.c
91 lines (75 loc) · 2.72 KB
/
az_context.c
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
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include <azure/core/az_context.h>
#include <azure/core/internal/az_precondition_internal.h>
#include <stddef.h>
#include <azure/core/_az_cfg.h>
// This is a global az_context node representing the entire application. By default, this node
// never expires. Call az_context_cancel passing a pointer to this node to cancel the entire
// application (which cancels all the child nodes).
az_context az_context_application = {
._internal
= { .parent = NULL, .expiration = _az_CONTEXT_MAX_EXPIRATION, .key = NULL, .value = NULL }
};
// Returns the soonest expiration time of this az_context node or any of its parent nodes.
AZ_NODISCARD int64_t az_context_get_expiration(az_context const* context)
{
_az_PRECONDITION_NOT_NULL(context);
int64_t expiration = _az_CONTEXT_MAX_EXPIRATION;
for (; context != NULL; context = context->_internal.parent)
{
if (context->_internal.expiration < expiration)
{
expiration = context->_internal.expiration;
}
}
return expiration;
}
// Walks up this az_context node's parent until it find a node whose key matches the specified key
// and return the corresponding value. Returns AZ_ERROR_ITEM_NOT_FOUND is there are no nodes
// matching the specified key.
AZ_NODISCARD az_result
az_context_get_value(az_context const* context, void const* key, void const** out_value)
{
_az_PRECONDITION_NOT_NULL(context);
_az_PRECONDITION_NOT_NULL(out_value);
_az_PRECONDITION_NOT_NULL(key);
for (; context != NULL; context = context->_internal.parent)
{
if (context->_internal.key == key)
{
*out_value = context->_internal.value;
return AZ_OK;
}
}
*out_value = NULL;
return AZ_ERROR_ITEM_NOT_FOUND;
}
AZ_NODISCARD az_context
az_context_create_with_expiration(az_context const* parent, int64_t expiration)
{
_az_PRECONDITION_NOT_NULL(parent);
_az_PRECONDITION(expiration >= 0);
return (az_context){ ._internal = { .parent = parent, .expiration = expiration } };
}
AZ_NODISCARD az_context
az_context_create_with_value(az_context const* parent, void const* key, void const* value)
{
_az_PRECONDITION_NOT_NULL(parent);
_az_PRECONDITION_NOT_NULL(key);
return (az_context){
._internal
= { .parent = parent, .expiration = _az_CONTEXT_MAX_EXPIRATION, .key = key, .value = value }
};
}
void az_context_cancel(az_context* ref_context)
{
_az_PRECONDITION_NOT_NULL(ref_context);
ref_context->_internal.expiration = 0; // The beginning of time
}
AZ_NODISCARD bool az_context_has_expired(az_context const* context, int64_t current_time)
{
_az_PRECONDITION_NOT_NULL(context);
_az_PRECONDITION(current_time >= 0);
return az_context_get_expiration(context) < current_time;
}