提交 eee03164 编写于 作者: J Jeff Mahoney 提交者: Greg Kroah-Hartman

kobject: introduce kobj_completion

A common way to handle kobject lifetimes in embedded in objects with
different lifetime rules is to pair the kobject with a struct completion.

This introduces a kobj_completion structure that can be used in place
of the pairing, along with several convenience functions for
initialization, release, and put-and-wait.
Signed-off-by: NJeff Mahoney <jeffm@suse.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 1296fc02
#ifndef _KOBJ_COMPLETION_H_
#define _KOBJ_COMPLETION_H_
#include <linux/kobject.h>
#include <linux/completion.h>
struct kobj_completion {
struct kobject kc_kobj;
struct completion kc_unregister;
};
#define kobj_to_kobj_completion(kobj) \
container_of(kobj, struct kobj_completion, kc_kobj)
void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype);
void kobj_completion_release(struct kobject *kobj);
void kobj_completion_del_and_wait(struct kobj_completion *kc);
#endif /* _KOBJ_COMPLETION_H_ */
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
*/ */
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/kobj_completion.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/stat.h> #include <linux/stat.h>
...@@ -749,6 +750,55 @@ const struct sysfs_ops kobj_sysfs_ops = { ...@@ -749,6 +750,55 @@ const struct sysfs_ops kobj_sysfs_ops = {
.store = kobj_attr_store, .store = kobj_attr_store,
}; };
/**
* kobj_completion_init - initialize a kobj_completion object.
* @kc: kobj_completion
* @ktype: type of kobject to initialize
*
* kobj_completion structures can be embedded within structures with different
* lifetime rules. During the release of the enclosing object, we can
* wait on the release of the kobject so that we don't free it while it's
* still busy.
*/
void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype)
{
init_completion(&kc->kc_unregister);
kobject_init(&kc->kc_kobj, ktype);
}
EXPORT_SYMBOL_GPL(kobj_completion_init);
/**
* kobj_completion_release - release a kobj_completion object
* @kobj: kobject embedded in kobj_completion
*
* Used with kobject_release to notify waiters that the kobject has been
* released.
*/
void kobj_completion_release(struct kobject *kobj)
{
struct kobj_completion *kc = kobj_to_kobj_completion(kobj);
complete(&kc->kc_unregister);
}
EXPORT_SYMBOL_GPL(kobj_completion_release);
/**
* kobj_completion_del_and_wait - release the kobject and wait for it
* @kc: kobj_completion object to release
*
* Delete the kobject from sysfs and drop the reference count. Then wait
* until any other outstanding references are also dropped. This routine
* is only necessary once other references may have been taken on the
* kobject. Typically this happens when the kobject has been published
* to sysfs via kobject_add.
*/
void kobj_completion_del_and_wait(struct kobj_completion *kc)
{
kobject_del(&kc->kc_kobj);
kobject_put(&kc->kc_kobj);
wait_for_completion(&kc->kc_unregister);
}
EXPORT_SYMBOL_GPL(kobj_completion_del_and_wait);
/** /**
* kset_register - initialize and add a kset. * kset_register - initialize and add a kset.
* @k: kset. * @k: kset.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册