266 |
console_switch (int id, int delta) |
console_switch (int id, int delta) |
267 |
{ |
{ |
268 |
error_t err = 0; |
error_t err = 0; |
|
int active_id; |
|
|
cons_t cons; |
|
269 |
vcons_t vcons; |
vcons_t vcons; |
270 |
|
vcons_t new_vcons; |
|
mutex_lock (&global_lock); |
|
|
if (!active_vcons) |
|
|
{ |
|
|
mutex_unlock (&global_lock); |
|
|
return 0; |
|
|
} |
|
|
cons = active_vcons->cons; |
|
|
active_id = active_vcons->id; |
|
271 |
|
|
272 |
/* We must give up our global lock before we can call back into |
/* We must give up our global lock before we can call back into |
273 |
libcons. This is because cons_switch will lock CONS, and as |
libcons. This is because cons_switch will lock CONS, and as |
274 |
other functions in libcons lock CONS while calling back into our |
other functions in libcons lock CONS while calling back into our |
275 |
functions which take the global lock (like cons_vcons_add), we |
functions which take the global lock (like cons_vcons_add), we |
276 |
would deadlock. Because of this, we can not refer to our active |
would deadlock. So we acquire a reference for VCONS to make sure |
277 |
console directly, but we must refer to it by name (ID). XXX |
it isn't deallocated while we are outside of the global lock. We |
278 |
Likewise, we can not really refer to CONS directly, but the |
also know that */ |
279 |
current implementation guarantees an eternal life span for |
|
280 |
CONS. */ |
mutex_lock (&global_lock); |
281 |
|
vcons = active_vcons; |
282 |
|
if (vcons) |
283 |
|
ports_port_ref (vcons); |
284 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
285 |
err = cons_switch (cons, active_id, id, delta, &vcons); |
|
286 |
|
err = cons_switch (vcons, id, delta, &new_vcons); |
287 |
if (!err) |
if (!err) |
288 |
{ |
{ |
289 |
mutex_lock (&global_lock); |
mutex_lock (&global_lock); |
290 |
if (active_vcons != vcons) |
if (active_vcons != new_vcons) |
291 |
{ |
{ |
292 |
cons_vcons_close (active_vcons); |
cons_vcons_close (active_vcons); |
293 |
active_vcons = vcons; |
active_vcons = new_vcons; |
294 |
} |
} |
295 |
mutex_unlock (&vcons->lock); |
mutex_unlock (&new_vcons->lock); |
296 |
|
ports_port_deref (vcons); |
297 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
298 |
} |
} |
299 |
return err; |
return err; |
300 |
} |
} |
301 |
|
|
302 |
|
|
303 |
void |
void |
304 |
cons_vcons_add (cons_t cons, vcons_list_t vcons_entry) |
cons_vcons_add (cons_t cons, vcons_list_t vcons_entry) |
305 |
{ |
{ |