diff options
author | Sergiu Ivanov <unlimitedscolobb@gmail.com> | 2009-04-12 22:31:26 +0300 |
---|---|---|
committer | Sergiu Ivanov <unlimitedscolobb@gmail.com> | 2009-04-12 22:31:26 +0300 |
commit | 0a5fcd403943fbbdc0a2ba35283f1135f97c48dc (patch) | |
tree | 538585395c4376368118a32d93e1c83569bf4a0d /trans.c | |
parent | 68c018b02a8eff826cd30480ce73202ce9cc9e48 (diff) |
Added dynamic translator tracking facilities
nsmux cannot presently shut down gracefully (without the -f option)
after having done a magic lookup, because the dynamic translators it
starts hold ports (references) to its nodes and make the standard
fsys_goaway handler return with EBUSY. To solve the problem, nsmux
will need to keep track of dynamic translators and shut them down
explicitly, not relying on standard mechanisms, which don't know that
the translators might be stacked and might try stopping a translator
in the middle of the dynamic stack, which will certainly result in
EBUSY.
(Note that this commit comes on top of an erroneous one and is meant
to fix it. I could not revert the previous commit because of ``bad
index'', so I hope this commit will solve the problem...)
Diffstat (limited to 'trans.c')
-rw-r--r-- | trans.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/trans.c b/trans.c new file mode 100644 index 000000000..8d05286ce --- /dev/null +++ b/trans.c @@ -0,0 +1,108 @@ +/*---------------------------------------------------------------------------*/ +/*trans.c*/ +/*---------------------------------------------------------------------------*/ +/*Facilities to keep track of dynamic translators.*/ +/*---------------------------------------------------------------------------*/ +/*Copyright (C) 2008, 2009 Free Software Foundation, Inc. Written by + Sergiu Ivanov <unlimitedscolobb@gmail.com>. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or * (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA.*/ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +#define _GNU_SOURCE 1 +/*---------------------------------------------------------------------------*/ +#include <stdlib.h> +#include <hurd/fsys.h> +/*---------------------------------------------------------------------------*/ +#include "trans.h" +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/*---------Variables---------------------------------------------------------*/ +/*The list of dynamic translators */ +trans_el_t * dyntrans = NULL; +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/*---------Functions---------------------------------------------------------*/ +/*Adds a translator control port to the list of ports. One should use + only this function to add a new element to the list of ports. */ +error_t +trans_register (mach_port_t cntl) +{ + /*The new entry in the list */ + trans_el_t * el; + + el = malloc (sizeof (trans_el_t)); + if (!el) + return ENOMEM; + + el->cntl = cntl; + + el->prev = NULL; + el->next = dyntrans; + dyntrans = el; + + return 0; +} /*trans_register */ + +/*---------------------------------------------------------------------------*/ +/*Removes a translator control port from the list of ports. One should + use only this function to remove an element from the list of + ports. This function does not shut down the translator. */ +void +trans_unregister (trans_el_t * trans) +{ + if (trans->prev) + trans->prev->next = trans->next; + if(trans->next) + trans->next->prev = trans->prev; + + free(trans); +} /*trans_unregister */ + +/*---------------------------------------------------------------------------*/ +/*Gracefully shuts down all the translators registered in the + list with `flags`. */ +error_t +trans_shutdown_all (int flags) +{ + error_t err; + + /*The element being dealt with now. */ + trans_el_t * el; + + for (el = dyntrans; el; el = el->next) + { + err = fsys_goaway (el->cntl, flags); + + if (err) + { + /*The error cannot happen because the translators are being + shut down in the incorrect order, so something is + wrong. Stop and update dyntrans. */ + + dyntrans = el; + return err; + } + } + + dyntrans = NULL; + return 0; +} /*trans_shutdown_all */ + +/*---------------------------------------------------------------------------*/ |