From 4b4a49fda59bd382f3bf4c7fb8a4fc5cb89f40b5 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Mon, 1 May 2000 10:45:15 +0000 Subject: [PATCH] * Move the driver_t::refs field to kobj_t to replace kobj_t::instances. * Back out a couple of workarounds for the confusion between kobj_t::instances and driver_t::refs. --- sys/kern/subr_bus.c | 11 ++++------- sys/kern/subr_kobj.c | 6 +++--- sys/sys/bus.h | 1 - sys/sys/kobj.h | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 22ad8120189..de36141d57b 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -162,7 +162,10 @@ devclass_add_driver(devclass_t dc, driver_t *driver) bzero(dl, sizeof *dl); /* - * Compile the driver's methods. + * Compile the driver's methods. Also increase the reference count + * so that the class doesn't get freed when the last instance + * goes. This means we can safely use static methods and avoids a + * double-free in devclass_delete_driver. */ kobj_class_compile((kobj_class_t) driver); @@ -986,7 +989,6 @@ device_set_driver(device_t dev, driver_t *driver) return ENOMEM; } bzero(dev->softc, driver->size); - driver->refs++; } else kobj_init((kobj_t) dev, &null_class); return 0; @@ -1843,11 +1845,6 @@ bus_generic_driver_added(device_t dev, driver_t *driver) { device_t child; - /* - * Make sure the class has a valid ops table. - */ - kobj_class_compile((kobj_class_t) driver); - DEVICE_IDENTIFY(driver, dev); for (child = TAILQ_FIRST(&dev->children); child; child = TAILQ_NEXT(child, link)) diff --git a/sys/kern/subr_kobj.c b/sys/kern/subr_kobj.c index 9a2eafb1812..6b95eb9d593 100644 --- a/sys/kern/subr_kobj.c +++ b/sys/kern/subr_kobj.c @@ -174,7 +174,7 @@ kobj_init(kobj_t obj, kobj_class_t cls) kobj_class_compile(cls); obj->ops = cls->ops; - cls->instances++; + cls->refs++; } void @@ -187,8 +187,8 @@ kobj_delete(kobj_t obj, struct malloc_type *mtype) * after its last instance is deleted. As an optimisation, we * should defer this for a short while to avoid thrashing. */ - cls->instances--; - if (!cls->instances) + cls->refs--; + if (!cls->refs) kobj_class_free(cls); obj->ops = 0; diff --git a/sys/sys/bus.h b/sys/sys/bus.h index f1ed037ec8b..8ab2a130a4c 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -65,7 +65,6 @@ typedef int (*devop_t)(void); struct driver { KOBJ_CLASS_FIELDS; void *priv; /* driver private data */ - int refs; /* # devclasses containing driver */ }; typedef enum device_state { diff --git a/sys/sys/kobj.h b/sys/sys/kobj.h index 906cf5aeead..f8500d58267 100644 --- a/sys/sys/kobj.h +++ b/sys/sys/kobj.h @@ -55,7 +55,7 @@ struct kobj_method { const char *name; /* class name */ \ kobj_method_t *methods; /* method table */ \ size_t size; /* object size */ \ - u_int instances; /* instance count */ \ + u_int refs; /* reference count */ \ kobj_ops_t ops /* compiled method table */ struct kobj_class {