Rev 1088 | Rev 1141 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1088 | Rev 1090 | ||
|---|---|---|---|
| Line 143... | Line 143... | ||
| 143 | */ |
143 | */ |
| 144 | static void _ipc_answer_free_call(call_t *call) |
144 | static void _ipc_answer_free_call(call_t *call) |
| 145 | { |
145 | { |
| 146 | answerbox_t *callerbox = call->callerbox; |
146 | answerbox_t *callerbox = call->callerbox; |
| 147 | 147 | ||
| 148 | call->flags &= ~IPC_CALL_DISPATCHED; |
- | |
| 149 | call->flags |= IPC_CALL_ANSWERED; |
148 | call->flags |= IPC_CALL_ANSWERED; |
| 150 | 149 | ||
| 151 | spinlock_lock(&callerbox->lock); |
150 | spinlock_lock(&callerbox->lock); |
| 152 | list_append(&call->list, &callerbox->answers); |
151 | list_append(&call->list, &callerbox->answers); |
| 153 | spinlock_unlock(&callerbox->lock); |
152 | spinlock_unlock(&callerbox->lock); |
| Line 167... | Line 166... | ||
| 167 | spinlock_unlock(&box->lock); |
166 | spinlock_unlock(&box->lock); |
| 168 | /* Send back answer */ |
167 | /* Send back answer */ |
| 169 | _ipc_answer_free_call(call); |
168 | _ipc_answer_free_call(call); |
| 170 | } |
169 | } |
| 171 | 170 | ||
| - | 171 | /** Simulate sending back a message |
|
| - | 172 | * |
|
| - | 173 | * Most errors are better handled by forming a normal backward |
|
| - | 174 | * message and sending it as a normal answer. |
|
| - | 175 | */ |
|
| - | 176 | void ipc_backsend_err(phone_t *phone, call_t *call, __native err) |
|
| - | 177 | { |
|
| - | 178 | call->data.phone = phone; |
|
| - | 179 | atomic_inc(&phone->active_calls); |
|
| - | 180 | if (phone->busy == IPC_BUSY_CONNECTED) |
|
| - | 181 | IPC_SET_RETVAL(call->data, EHANGUP); |
|
| - | 182 | else |
|
| - | 183 | IPC_SET_RETVAL(call->data, ENOENT); |
|
| - | 184 | ||
| - | 185 | _ipc_answer_free_call(call); |
|
| - | 186 | } |
|
| - | 187 | ||
| 172 | /* Unsafe unchecking ipc_call */ |
188 | /* Unsafe unchecking ipc_call */ |
| 173 | static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call) |
189 | static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call) |
| 174 | { |
190 | { |
| 175 | if (! (call->flags & IPC_CALL_FORWARDED)) { |
191 | if (! (call->flags & IPC_CALL_FORWARDED)) { |
| 176 | atomic_inc(&phone->active_calls); |
192 | atomic_inc(&phone->active_calls); |
| Line 198... | Line 214... | ||
| 198 | if (!box) { |
214 | if (!box) { |
| 199 | /* Trying to send over disconnected phone */ |
215 | /* Trying to send over disconnected phone */ |
| 200 | spinlock_unlock(&phone->lock); |
216 | spinlock_unlock(&phone->lock); |
| 201 | if (call->flags & IPC_CALL_FORWARDED) { |
217 | if (call->flags & IPC_CALL_FORWARDED) { |
| 202 | IPC_SET_RETVAL(call->data, EFORWARD); |
218 | IPC_SET_RETVAL(call->data, EFORWARD); |
| - | 219 | _ipc_answer_free_call(call); |
|
| 203 | } else { /* Simulate sending a message */ |
220 | } else { /* Simulate sending back a message */ |
| 204 | call->data.phone = phone; |
- | |
| 205 | atomic_inc(&phone->active_calls); |
- | |
| 206 | if (phone->busy == IPC_BUSY_CONNECTED) |
221 | if (phone->busy == IPC_BUSY_CONNECTED) |
| 207 | IPC_SET_RETVAL(call->data, EHANGUP); |
222 | ipc_backsend_err(phone, call, EHANGUP); |
| 208 | else |
223 | else |
| 209 | IPC_SET_RETVAL(call->data, ENOENT); |
224 | ipc_backsend_err(phone, call, ENOENT); |
| 210 | } |
225 | } |
| 211 | 226 | ||
| 212 | _ipc_answer_free_call(call); |
- | |
| 213 | return ENOENT; |
227 | return ENOENT; |
| 214 | } |
228 | } |
| 215 | _ipc_call(phone, box, call); |
229 | _ipc_call(phone, box, call); |
| 216 | 230 | ||
| 217 | spinlock_unlock(&phone->lock); |
231 | spinlock_unlock(&phone->lock); |
| Line 305... | Line 319... | ||
| 305 | /* Handle requests */ |
319 | /* Handle requests */ |
| 306 | request = list_get_instance(box->calls.next, call_t, list); |
320 | request = list_get_instance(box->calls.next, call_t, list); |
| 307 | list_remove(&request->list); |
321 | list_remove(&request->list); |
| 308 | /* Append request to dispatch queue */ |
322 | /* Append request to dispatch queue */ |
| 309 | list_append(&request->list, &box->dispatched_calls); |
323 | list_append(&request->list, &box->dispatched_calls); |
| 310 | request->flags |= IPC_CALL_DISPATCHED; |
- | |
| 311 | } else { |
324 | } else { |
| 312 | printf("WARNING: Spurious IPC wakeup.\n"); |
325 | printf("WARNING: Spurious IPC wakeup.\n"); |
| 313 | spinlock_unlock(&box->lock); |
326 | spinlock_unlock(&box->lock); |
| 314 | goto restart; |
327 | goto restart; |
| 315 | } |
328 | } |