File: future.c.template

package info (click to toggle)
mongo-c-driver 2.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 47,088 kB
  • sloc: ansic: 193,670; python: 7,780; cpp: 1,493; sh: 659; makefile: 78
file content (129 lines) | stat: -rw-r--r-- 3,048 bytes parent folder | download | duplicates (2)
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
#include <stdio.h>

#include <mongoc/mongoc-array-private.h>
#include <mongoc/mongoc-thread-private.h>
#include "mock_server/future.h"
#include "../test-libmongoc.h"

{{ header_comment }}

#define FUTURE_TIMEOUT_ABORT                         \
   if (1) {                                          \
      fflush (stdout);                               \
      fprintf (stderr, "%s timed out\n", BSON_FUNC); \
      fflush (stderr);                               \
      abort ();                                      \
   } else                                            \
      ((void) 0)

void
future_get_void (future_t *future)
{
   if (future_wait (future)) {
      return;
   }

   FUTURE_TIMEOUT_ABORT;
}

{% for T in type_list %}
{{ T }}
future_get_{{ T }} (future_t *future)
{
   if (future_wait (future)) {
      return future_value_get_{{ T }} (&future->return_value);
   }

   FUTURE_TIMEOUT_ABORT;
}
{% endfor %}

future_t *
future_new (future_value_type_t return_type, int argc)
{
   future_t *future;

   future = (future_t *)bson_malloc0 (sizeof *future);
   future->return_value.type = return_type;
   future->argc = argc;
   future->argv = (future_value_t *)bson_malloc0 ((size_t) argc * sizeof(future_value_t));
   mongoc_cond_init (&future->cond);
   bson_mutex_init (&future->mutex);

   return future;
}

future_value_t *
future_get_param (future_t *future, int i)
{
   return &future->argv[i];
}

void
future_start (future_t *future,
              BSON_THREAD_FUN_TYPE (start_routine))
{
   int r = mcommon_thread_create (&future->thread,
                                  start_routine,
                                  (void *) future);

   BSON_ASSERT (!r);
}


void
future_resolve (future_t *future, future_value_t return_value)
{
   bson_mutex_lock (&future->mutex);
   BSON_ASSERT (!future->resolved);
   BSON_ASSERT (future->return_value.type == return_value.type);
   future->return_value = return_value;
   future->resolved = true;
   mongoc_cond_signal (&future->cond);
   bson_mutex_unlock (&future->mutex);
}


bool
future_wait_max (future_t *future, int64_t timeout_ms)
{
   int64_t remaining_usec = timeout_ms * 1000;
   int64_t deadline = bson_get_monotonic_time () + timeout_ms * 1000;
   bool resolved;

   bson_mutex_lock (&future->mutex);
   while (!future->resolved && remaining_usec > 0) {
      mongoc_cond_timedwait (&future->cond, &future->mutex,
                             remaining_usec / 1000);
      remaining_usec = deadline - bson_get_monotonic_time ();
   }
   resolved = future->resolved;
   bson_mutex_unlock (&future->mutex);

   if (resolved) {
      future->awaited = true;

      /* free memory */
      mcommon_thread_join (future->thread);
   }

   return resolved;
}


bool
future_wait (future_t *future)
{
   return future_wait_max (future, get_future_timeout_ms ());
}


void
future_destroy (future_t *future)
{
   BSON_ASSERT (future->awaited);
   bson_free (future->argv);
   mongoc_cond_destroy (&future->cond);
   bson_mutex_destroy (&future->mutex);
   bson_free (future);
}