summaryrefslogtreecommitdiffstats
path: root/meta-ivi/recipes-core-ivi/dbus/dbus/capi-dbus-add-send-with-reply-set-notify.patch
blob: fee91c3e099517e7d7f793475f643a1b96f603bb (plain)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
From 1dcacc908826f59b580bd1d1a7541fb919d4bd97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=BCrgen=20Gehring?= <juergen.gehring@bmw.de>
Date: Thu, 23 Apr 2015 02:15:06 -0700
Subject: [PATCH] Add dbus_connection_send_with_reply_set_notify function for
 proper thread handling

---
 dbus/dbus-connection.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++
 dbus/dbus-connection.h |  10 ++++
 2 files changed, 165 insertions(+)

diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index e1068e3..233f179 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -3482,6 +3482,161 @@ dbus_connection_send_with_reply (DBusConnection     *connection,
 }
 
 /**
+ * Queues a message to send, as with dbus_connection_send(),
+ * but also returns a #DBusPendingCall used to receive a reply to the
+ * message. If no reply is received in the given timeout_milliseconds,
+ * this function expires the pending reply and generates a synthetic
+ * error reply (generated in-process, not by the remote application)
+ * indicating that a timeout occurred.
+ *
+ * A #DBusPendingCall will see a reply message before any filters or
+ * registered object path handlers. See dbus_connection_dispatch() for
+ * details on when handlers are run.
+ *
+ * A #DBusPendingCall will always see exactly one reply message,
+ * unless it's cancelled with dbus_pending_call_cancel().
+ *
+ * If #NULL is passed for the pending_return, the #DBusPendingCall
+ * will still be generated internally, and used to track
+ * the message reply timeout. This means a timeout error will
+ * occur if no reply arrives, unlike with dbus_connection_send().
+ *
+ * If -1 is passed for the timeout, a sane default timeout is used. -1
+ * is typically the best value for the timeout for this reason, unless
+ * you want a very short or very long timeout.  If #DBUS_TIMEOUT_INFINITE is
+ * passed for the timeout, no timeout will be set and the call will block
+ * forever.
+ *
+ * @warning if the connection is disconnected or you try to send Unix
+ * file descriptors on a connection that does not support them, the
+ * #DBusPendingCall will be set to #NULL, so be careful with this.
+ *
+ * @param connection the connection
+ * @param message the message to send
+ * @param pending_return return location for a #DBusPendingCall
+ * object, or #NULL if connection is disconnected or when you try to
+ * send Unix file descriptors on a connection that does not support
+ * them.
+ * @param timeout_milliseconds timeout in milliseconds, -1 (or
+ *  #DBUS_TIMEOUT_USE_DEFAULT) for default or #DBUS_TIMEOUT_INFINITE for no
+ *  timeout
+ * @returns #FALSE if no memory, #TRUE otherwise.
+ *
+ */
+dbus_bool_t
+dbus_connection_send_with_reply_set_notify (DBusConnection     *connection,
+                                 DBusMessage        *message,
+                                 DBusPendingCall   **pending_return,
+                                 DBusPendingCallNotifyFunction function0,
+                                 void               *user_data0,
+                                 DBusFreeFunction    free_user_data0,
+                                 int                 timeout_milliseconds)
+{
+  DBusPendingCall *pending;
+  dbus_int32_t serial = -1;
+  DBusDispatchStatus status;
+
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+  _dbus_return_val_if_fail (message != NULL, FALSE);
+  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
+
+  if (pending_return)
+    *pending_return = NULL;
+
+  CONNECTION_LOCK (connection);
+
+#ifdef HAVE_UNIX_FD_PASSING
+
+  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
+      message->n_unix_fds > 0)
+    {
+      /* Refuse to send fds on a connection that cannot handle
+         them. Unfortunately we cannot return a proper error here, so
+         the best we can do is return TRUE but leave *pending_return
+         as NULL. */
+      CONNECTION_UNLOCK (connection);
+      return TRUE;
+    }
+
+#endif
+
+   if (!_dbus_connection_get_is_connected_unlocked (connection))
+    {
+      CONNECTION_UNLOCK (connection);
+
+      return TRUE;
+    }
+
+  pending = _dbus_pending_call_new_unlocked (connection,
+                                             timeout_milliseconds,
+                                             reply_handler_timeout);
+
+  CONNECTION_UNLOCK (connection);
+  if (pending == NULL)
+    {
+      return FALSE;
+    }
+
+  if (!dbus_pending_call_set_notify(pending, function0, user_data0, free_user_data0))
+    {
+      return FALSE;
+    }
+  CONNECTION_LOCK (connection);
+
+  /* Assign a serial to the message */
+  serial = dbus_message_get_serial (message);
+  if (serial == 0)
+    {
+      serial = _dbus_connection_get_next_client_serial (connection);
+      dbus_message_set_serial (message, serial);
+    }
+
+  if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
+    goto error;
+
+  /* Insert the serial in the pending replies hash;
+   * hash takes a refcount on DBusPendingCall.
+   * Also, add the timeout.
+   */
+  if (!_dbus_connection_attach_pending_call_unlocked (connection,
+						      pending))
+    goto error;
+
+  if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
+    {
+      _dbus_connection_detach_pending_call_and_unlock (connection,
+						       pending);
+      goto error_unlocked;
+    }
+
+  if (pending_return)
+    *pending_return = pending; /* hand off refcount */
+  else
+    {
+      _dbus_connection_detach_pending_call_unlocked (connection, pending);
+      /* we still have a ref to the pending call in this case, we unref
+       * after unlocking, below
+       */
+    }
+
+  status = _dbus_connection_get_dispatch_status_unlocked (connection);
+
+  /* this calls out to user code */
+  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
+
+  if (pending_return == NULL)
+    dbus_pending_call_unref (pending);
+
+  return TRUE;
+
+ error:
+  CONNECTION_UNLOCK (connection);
+ error_unlocked:
+  dbus_pending_call_unref (pending);
+  return FALSE;
+}
+
+/**
  * Sends a message and blocks a certain time period while waiting for
  * a reply.  This function does not reenter the main loop,
  * i.e. messages other than the reply are queued up but not
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index fe4d04e..e8cedf1 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -229,6 +229,16 @@ dbus_bool_t        dbus_connection_send_with_reply              (DBusConnection
                                                                  DBusMessage                *message,
                                                                  DBusPendingCall           **pending_return,
                                                                  int                         timeout_milliseconds);
+
+DBUS_EXPORT
+dbus_bool_t        dbus_connection_send_with_reply_set_notify   (DBusConnection             *connection,
+                                                                 DBusMessage                *message,
+                                                                 DBusPendingCall           **pending_return,
+                                                                 DBusPendingCallNotifyFunction function0,
+                                                                 void                      * user_data0,
+                                                                 DBusFreeFunction            free_user_data0,
+                                                                 int                         timeout_milliseconds);
+
 DBUS_EXPORT
 DBusMessage *      dbus_connection_send_with_reply_and_block    (DBusConnection             *connection,
                                                                  DBusMessage                *message,
-- 
1.9.1