]> git.proxmox.com Git - ovs.git/blob - ovsdb/trigger.c
dpif-netdev: Change polled_queue to use dp_netdev_rxq.
[ovs.git] / ovsdb / trigger.c
1 /* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <config.h>
17
18 #include "trigger.h"
19
20 #include <limits.h>
21
22 #include "openvswitch/json.h"
23 #include "jsonrpc.h"
24 #include "ovsdb.h"
25 #include "poll-loop.h"
26 #include "server.h"
27
28 static bool ovsdb_trigger_try(struct ovsdb_trigger *, long long int now);
29 static void ovsdb_trigger_complete(struct ovsdb_trigger *);
30
31 void
32 ovsdb_trigger_init(struct ovsdb_session *session, struct ovsdb *db,
33 struct ovsdb_trigger *trigger,
34 struct json *request, long long int now,
35 bool read_only, const char *role,
36 const char *id)
37 {
38 trigger->session = session;
39 trigger->db = db;
40 ovs_list_push_back(&trigger->db->triggers, &trigger->node);
41 trigger->request = request;
42 trigger->result = NULL;
43 trigger->created = now;
44 trigger->timeout_msec = LLONG_MAX;
45 trigger->read_only = read_only;
46 trigger->role = nullable_xstrdup(role);
47 trigger->id = nullable_xstrdup(id);
48 ovsdb_trigger_try(trigger, now);
49 }
50
51 void
52 ovsdb_trigger_destroy(struct ovsdb_trigger *trigger)
53 {
54 ovs_list_remove(&trigger->node);
55 json_destroy(trigger->request);
56 json_destroy(trigger->result);
57 free(trigger->role);
58 free(trigger->id);
59 }
60
61 bool
62 ovsdb_trigger_is_complete(const struct ovsdb_trigger *trigger)
63 {
64 return trigger->result != NULL;
65 }
66
67 struct json *
68 ovsdb_trigger_steal_result(struct ovsdb_trigger *trigger)
69 {
70 struct json *result = trigger->result;
71 trigger->result = NULL;
72 return result;
73 }
74
75 void
76 ovsdb_trigger_run(struct ovsdb *db, long long int now)
77 {
78 struct ovsdb_trigger *t, *next;
79 bool run_triggers;
80
81 run_triggers = db->run_triggers;
82 db->run_triggers = false;
83 LIST_FOR_EACH_SAFE (t, next, node, &db->triggers) {
84 if (run_triggers || now - t->created >= t->timeout_msec) {
85 ovsdb_trigger_try(t, now);
86 }
87 }
88 }
89
90 void
91 ovsdb_trigger_wait(struct ovsdb *db, long long int now)
92 {
93 if (db->run_triggers) {
94 poll_immediate_wake();
95 } else {
96 long long int deadline = LLONG_MAX;
97 struct ovsdb_trigger *t;
98
99 LIST_FOR_EACH (t, node, &db->triggers) {
100 if (t->created < LLONG_MAX - t->timeout_msec) {
101 long long int t_deadline = t->created + t->timeout_msec;
102 if (deadline > t_deadline) {
103 deadline = t_deadline;
104 if (now >= deadline) {
105 break;
106 }
107 }
108 }
109 }
110
111 if (deadline < LLONG_MAX) {
112 poll_timer_wait_until(deadline);
113 }
114 }
115 }
116
117 static bool
118 ovsdb_trigger_try(struct ovsdb_trigger *t, long long int now)
119 {
120 t->result = ovsdb_execute(t->db, t->session,
121 t->request, t->read_only,
122 t->role, t->id,
123 now - t->created, &t->timeout_msec);
124 if (t->result) {
125 ovsdb_trigger_complete(t);
126 return true;
127 } else {
128 return false;
129 }
130 }
131
132 static void
133 ovsdb_trigger_complete(struct ovsdb_trigger *t)
134 {
135 ovs_assert(t->result != NULL);
136 ovs_list_remove(&t->node);
137 ovs_list_push_back(&t->session->completions, &t->node);
138 }