qemu

Форк
0
/
qemu-co-timeout.c 
89 строк · 2.7 Кб
1
/*
2
 * Helper functionality for distributing a fixed total amount of
3
 * an abstract resource among multiple coroutines.
4
 *
5
 * Copyright (c) 2022 Virtuozzo International GmbH
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25

26
#include "qemu/osdep.h"
27
#include "qemu/coroutine.h"
28
#include "block/aio.h"
29

30
typedef struct QemuCoTimeoutState {
31
    CoroutineEntry *entry;
32
    void *opaque;
33
    QemuCoSleep sleep_state;
34
    bool marker;
35
    CleanupFunc *clean;
36
} QemuCoTimeoutState;
37

38
static void coroutine_fn qemu_co_timeout_entry(void *opaque)
39
{
40
    QemuCoTimeoutState *s = opaque;
41

42
    s->entry(s->opaque);
43

44
    if (s->marker) {
45
        assert(!s->sleep_state.to_wake);
46
        /* .marker set by qemu_co_timeout, it have been failed */
47
        if (s->clean) {
48
            s->clean(s->opaque);
49
        }
50
        g_free(s);
51
    } else {
52
        s->marker = true;
53
        qemu_co_sleep_wake(&s->sleep_state);
54
    }
55
}
56

57
int coroutine_fn qemu_co_timeout(CoroutineEntry *entry, void *opaque,
58
                                 uint64_t timeout_ns, CleanupFunc clean)
59
{
60
    QemuCoTimeoutState *s;
61
    Coroutine *co;
62

63
    if (timeout_ns == 0) {
64
        entry(opaque);
65
        return 0;
66
    }
67

68
    s = g_new(QemuCoTimeoutState, 1);
69
    *s = (QemuCoTimeoutState) {
70
        .entry = entry,
71
        .opaque = opaque,
72
        .clean = clean
73
    };
74

75
    co = qemu_coroutine_create(qemu_co_timeout_entry, s);
76

77
    aio_co_enter(qemu_get_current_aio_context(), co);
78
    qemu_co_sleep_ns_wakeable(&s->sleep_state, QEMU_CLOCK_REALTIME, timeout_ns);
79

80
    if (s->marker) {
81
        /* .marker set by qemu_co_timeout_entry, success */
82
        g_free(s);
83
        return 0;
84
    }
85

86
    /* Don't free s, as we can't cancel qemu_co_timeout_entry execution */
87
    s->marker = true;
88
    return -ETIMEDOUT;
89
}
90

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.