少年修仙传客户端基础资源
hch
2024-04-01 d01413b00ef631ac20347716b23818b0b811f65f
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
/**
 * \file
 * Portability wrappers around POSIX Mutexes
 *
 * Authors: Jeffrey Stedfast <fejj@ximian.com>
 *
 * Copyright 2002 Ximian, Inc. (www.ximian.com)
 *
 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
 *
 */
 
#include <config.h>
 
#if !defined(HOST_WIN32)
 
#if defined(TARGET_OSX)
/* So we can use the declaration of pthread_cond_timedwait_relative_np () */
#undef _XOPEN_SOURCE
#endif
#include <pthread.h>
 
#include "mono-os-mutex.h"
 
int
mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
{
    struct timespec ts;
    int res;
 
    if (timeout_ms == MONO_INFINITE_WAIT) {
        mono_os_cond_wait (cond, mutex);
        return 0;
    }
 
    /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
 
    /* This function only seems to be available on 64bit osx */
#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP) && defined(TARGET_OSX)
    memset (&ts, 0, sizeof (struct timespec));
    ts.tv_sec = timeout_ms / 1000;
    ts.tv_nsec = (timeout_ms % 1000) * 1000 * 1000;
 
    res = pthread_cond_timedwait_relative_np (cond, mutex, &ts);
    if (G_UNLIKELY (res != 0 && res != ETIMEDOUT)) {
        g_print ("cond: %p mutex: %p\n", *(gpointer*)cond, *(gpointer*)mutex);
        g_error ("%s: pthread_cond_timedwait_relative_np failed with \"%s\" (%d) %ld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms);
    }
    return res != 0 ? -1 : 0;
#else
#ifdef BROKEN_CLOCK_SOURCE
    struct timeval tv;
 
    /* clock_gettime is not supported in MAC OS x */
    res = gettimeofday (&tv, NULL);
    if (G_UNLIKELY (res != 0))
        g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 
    ts.tv_sec = tv.tv_sec;
    ts.tv_nsec = tv.tv_usec * 1000;
#else
    /* cond is using CLOCK_MONOTONIC as time source */
    res = clock_gettime (CLOCK_MONOTONIC, &ts);
    if (G_UNLIKELY (res != 0))
        g_error ("%s: clock_gettime failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
#endif
 
    ts.tv_sec += timeout_ms / 1000;
    ts.tv_nsec += (timeout_ms % 1000) * 1000 * 1000;
    if (ts.tv_nsec >= 1000 * 1000 * 1000) {
        ts.tv_nsec -= 1000 * 1000 * 1000;
        ts.tv_sec ++;
    }
 
    res = pthread_cond_timedwait (cond, mutex, &ts);
    if (G_UNLIKELY (res != 0 && res != ETIMEDOUT)) {
        g_print ("cond: %p mutex: %p\n", *(gpointer*)cond, *(gpointer*)mutex);
        g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %ld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms);
    }
    return res != 0 ? -1 : 0;
#endif /* !HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP */
}
 
#endif /* HOST_WIN32 */