summaryrefslogtreecommitdiff
path: root/trans.c
diff options
context:
space:
mode:
authorSergiu Ivanov <unlimitedscolobb@gmail.com>2009-04-12 22:31:26 +0300
committerSergiu Ivanov <unlimitedscolobb@gmail.com>2009-04-12 22:31:26 +0300
commit0a5fcd403943fbbdc0a2ba35283f1135f97c48dc (patch)
tree538585395c4376368118a32d93e1c83569bf4a0d /trans.c
parent68c018b02a8eff826cd30480ce73202ce9cc9e48 (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.c108
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 */
+
+/*---------------------------------------------------------------------------*/