Subversion Repositories HelenOS

Rev

Rev 1088 | Rev 1141 | Go to most recent revision | Show entire file | Regard 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
    }