Hello,
On Sun, 8 Nov 2026 16:44:29 Samuel Thibault wrote:
> > Also, what is the correct way to deallocate a port_bucket? Judging by
> > create-bucket.c, a single call to free (port_bucket) is not sufficient.
>
> It seems so, according to the hurd_ihash_destroy call at least.
>
> > Perhaps it would be worth adding a dedicated function for this in
libports?
>
> Yes, it should have been done already :)
>
> It should probably assert that the ihash is already empty and the
> threadpool is empty.
I think we can do it this way.
Thanks,
--
Mikhail Karpov
From b766cbc05d64c3be338a02c96c25fb87034f99f4 Mon Sep 17 00:00:00 2001
From: Mikhail Karpov <[email protected]>
Date: Mon, 9 Nov 2026 12:43:05 +0700
Subject: [PATCH 2/3] Added a function that destroys a bucket
---
libports/Makefile | 2 +-
libports/create-bucket.c | 10 ++++------
libports/destroy-bucket.c | 33 +++++++++++++++++++++++++++++++++
libports/ports.h | 3 +++
4 files changed, 41 insertions(+), 7 deletions(-)
create mode 100644 libports/destroy-bucket.c
diff --git a/libports/Makefile b/libports/Makefile
index c67d8fe..bc95330 100644
--- a/libports/Makefile
+++ b/libports/Makefile
@@ -21,7 +21,7 @@ dir := libports
makemode := library
libname = libports
-SRCS = create-bucket.c create-class.c \
+SRCS = create-bucket.c create-class.c destroy-bucket.c \
reallocate-port.c reallocate-from-external.c destroy-right.c \
lookup-port.c port-ref.c port-ref-weak.c port-deref.c port-deref-weak.c \
no-senders.c begin-rpc.c end-rpc.c manage-one-thread.c manage-multithread.c \
diff --git a/libports/create-bucket.c b/libports/create-bucket.c
index 4c82786..0e291d7 100644
--- a/libports/create-bucket.c
+++ b/libports/create-bucket.c
@@ -42,10 +42,7 @@ ports_create_bucket (void)
ret = malloc (sizeof (struct port_bucket));
if (! ret)
- {
- errno = ENOMEM;
- return NULL;
- }
+ return NULL;
err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
&ret->portset);
@@ -63,10 +60,11 @@ ports_create_bucket (void)
/* Create the notify_port for this bucket. */
pthread_once (&init_notify_port_class_once, init_notify_port_class);
err = ports_create_port (notify_port_class, ret,
- sizeof (struct port_info),
- &ret->notify_port);
+ sizeof (struct port_info),
+ &ret->notify_port);
if (err)
{
+ mach_port_deallocate (mach_task_self (), ret->portset);
hurd_ihash_destroy (&ret->htable);
free (ret);
errno = err;
diff --git a/libports/destroy-bucket.c b/libports/destroy-bucket.c
new file mode 100644
index 0000000..4909b16
--- /dev/null
+++ b/libports/destroy-bucket.c
@@ -0,0 +1,33 @@
+/* Destroy the bucket.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd 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, or (at
+ your option) any later version.
+
+ The GNU Hurd 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, USA. */
+
+#include "ports.h"
+
+void
+ports_destroy_bucket (struct port_bucket *bucket)
+{
+ assert_backtrace (bucket->htable.nr_items == 0);
+ assert_backtrace (bucket->threadpool.old_threads == 0
+ && bucket->threadpool.young_threads == 0);
+
+ mach_port_deallocate (mach_task_self (), bucket->portset);
+ ports_port_deref (bucket->notify_port);
+ hurd_ihash_destroy (&bucket->htable);
+ free (bucket);
+}
diff --git a/libports/ports.h b/libports/ports.h
index 072c8a0..b946618 100644
--- a/libports/ports.h
+++ b/libports/ports.h
@@ -175,6 +175,9 @@ struct port_bucket *ports_create_bucket (void);
struct port_class *ports_create_class (void (*clean_routine)(void *),
void (*dropweak_routine)(void *));
+/* Destroy the BUCKET. */
+void ports_destroy_bucket (struct port_bucket *bucket);
+
/* Create and return in RESULT a new port in CLASS and BUCKET; SIZE bytes
will be allocated to hold the port structure and whatever private data the
user desires. */
--
2.43.0
From 92bdbee83b8d8fc10c96183a0988955d7d565691 Mon Sep 17 00:00:00 2001
From: Mikhail Karpov <[email protected]>
Date: Mon, 9 Nov 2026 12:44:54 +0700
Subject: [PATCH 3/3] Added check for ports_create_bucket in storeio/pager.c
---
storeio/pager.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/storeio/pager.c b/storeio/pager.c
index 7a26efa..8e0bc4b 100644
--- a/storeio/pager.c
+++ b/storeio/pager.c
@@ -145,9 +145,10 @@ static struct port_bucket *pager_port_bucket = 0;
static struct pager_requests *pager_requests;
/* Initialize paging for this device. */
-static void
+static error_t
init_dev_paging (void)
{
+ error_t err = 0;
if (! pager_port_bucket)
{
static pthread_mutex_t pager_global_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -155,20 +156,30 @@ init_dev_paging (void)
pthread_mutex_lock (&pager_global_lock);
if (pager_port_bucket == NULL)
{
- error_t err;
-
- pager_port_bucket = ports_create_bucket ();
+ struct port_bucket *bucket = ports_create_bucket ();
+ if (! bucket)
+ {
+ err = errno;
+ error (0, err, "ports_create_bucket");
+ goto out;
+ }
/* Start libpagers worker threads. */
- err = pager_start_workers (pager_port_bucket, &pager_requests);
+ err = pager_start_workers (bucket, &pager_requests);
if (err)
{
- errno = err;
+ ports_destroy_bucket (bucket);
error (0, err, "pager_start_workers");
}
+ else
+ pager_port_bucket = bucket;
}
+
+ out:
pthread_mutex_unlock (&pager_global_lock);
}
+
+ return err;
}
void
@@ -229,7 +240,9 @@ dev_get_memory_object (struct dev *dev, vm_prot_t prot, memory_object_t *memobj)
{
int created = 0;
- init_dev_paging ();
+ err = init_dev_paging ();
+ if (err)
+ return err;
pthread_mutex_lock (&dev->pager_lock);
--
2.43.0