From 608e5c5614b5993cf99713a5ff76da6eecb64b4b Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 27 Sep 2022 12:56:20 +0000 Subject: [PATCH] Improved interface of referenced objects, simpler use. Made all release() method implementations in VFS to be thread-safe. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15804 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../utils/include/oop_referenced_object.h | 10 ++++--- os/vfs/drivers/fatfs/drvfatfs.c | 26 +++++++++++++------ os/vfs/drivers/overlay/drvoverlay.c | 13 +++++++--- os/vfs/drivers/sfs/drvsfs.c | 26 +++++++++++++------ os/vfs/drivers/streams/drvstreams.c | 26 +++++++++++++------ os/vfs/drivers/template/drvtemplate.c | 26 +++++++++++++------ 6 files changed, 88 insertions(+), 39 deletions(-) diff --git a/os/common/utils/include/oop_referenced_object.h b/os/common/utils/include/oop_referenced_object.h index 9e90a410f..e4cbae118 100644 --- a/os/common/utils/include/oop_referenced_object.h +++ b/os/common/utils/include/oop_referenced_object.h @@ -43,7 +43,7 @@ typedef struct referenced_object referenced_object_c; #define __referenced_object_methods \ __base_object_methods \ void *(*addref)(void *ip); \ - void (*release)(void *ip); + unsigned (*release)(void *ip); /** * @brief @p referenced_object_c specific data. @@ -138,9 +138,10 @@ static inline unsigned __referenced_object_getref_impl(void *ip) { * @brief Reference release implementation. * * @param[in] ip A reference to the object. + * @return The number of references left. */ CC_FORCE_INLINE -static inline void __referenced_object_release_impl(void *ip) { +static inline unsigned __referenced_object_release_impl(void *ip) { referenced_object_c *objp = (referenced_object_c *)ip; osalDbgAssert(objp->references > 0U, "zero references"); @@ -148,6 +149,8 @@ static inline void __referenced_object_release_impl(void *ip) { if (--objp->references == 0U) { __referenced_object_dispose_impl(ip); } + + return objp->references; } /** @} */ @@ -168,9 +171,10 @@ static inline referenced_object_c *roAddRef(void *ip) { * @brief Reference release. * * @param[in] ip A reference to the object. + * @return The number of references left. */ CC_FORCE_INLINE -static inline void roRelease(void *ip) { +static inline unsigned roRelease(void *ip) { referenced_object_c *objp = (referenced_object_c *)ip; return objp->vmt->release(ip); diff --git a/os/vfs/drivers/fatfs/drvfatfs.c b/os/vfs/drivers/fatfs/drvfatfs.c index e006b31ea..8c4cc470b 100644 --- a/os/vfs/drivers/fatfs/drvfatfs.c +++ b/os/vfs/drivers/fatfs/drvfatfs.c @@ -138,7 +138,7 @@ static const struct vfs_fatfs_driver_vmt driver_vmt = { }; static void *node_dir_addref(void *instance); -static void node_dir_release(void *instance); +static unsigned node_dir_release(void *instance); static msg_t node_dir_stat(void *instance, vfs_stat_t *sp); static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip); static msg_t node_dir_next(void *instance, vfs_direntry_info_t *dip); @@ -152,7 +152,7 @@ static const struct vfs_fatfs_dir_node_vmt dir_node_vmt = { }; static void *node_file_addref(void *instance); -static void node_file_release(void *instance); +static unsigned node_file_release(void *instance); static msg_t node_file_stat(void *instance, vfs_stat_t *sp); static BaseSequentialStream *node_file_get_stream(void *instance); static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); @@ -519,14 +519,19 @@ static void *node_dir_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_dir_release(void *instance) { +static unsigned node_dir_release(void *instance) { vfs_fatfs_dir_node_c *ffdnp = (vfs_fatfs_dir_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_fatfs_driver_static.dir_nodes_pool, (void *)ffdnp); } + + return references; } static msg_t node_dir_stat(void *instance, vfs_stat_t *sp) { @@ -599,14 +604,19 @@ static void *node_file_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_file_release(void *instance) { +static unsigned node_file_release(void *instance) { vfs_fatfs_file_node_c *fffnp = (vfs_fatfs_file_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_fatfs_driver_static.file_nodes_pool, (void *)fffnp); } + + return references; } static msg_t node_file_stat(void *instance, vfs_stat_t *sp) { diff --git a/os/vfs/drivers/overlay/drvoverlay.c b/os/vfs/drivers/overlay/drvoverlay.c index 5a46ff1ad..5da242301 100644 --- a/os/vfs/drivers/overlay/drvoverlay.c +++ b/os/vfs/drivers/overlay/drvoverlay.c @@ -70,7 +70,7 @@ static const struct vfs_overlay_driver_vmt driver_vmt = { }; static void *node_dir_addref(void *instance); -static void node_dir_release(void *instance); +static unsigned node_dir_release(void *instance); static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip); static msg_t node_dir_next(void *instance, vfs_direntry_info_t *dip); @@ -763,11 +763,14 @@ static void *node_dir_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_dir_release(void *instance) { +static unsigned node_dir_release(void *instance) { vfs_overlay_dir_node_c *odnp = (vfs_overlay_dir_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { if (odnp->overlaid_root != NULL) { odnp->overlaid_root->vmt->release((void *)odnp->overlaid_root); @@ -775,6 +778,8 @@ static void node_dir_release(void *instance) { chPoolFree(&vfs_overlay_driver_static.dir_nodes_pool, (void *)odnp); } + + return references; } static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip) { diff --git a/os/vfs/drivers/sfs/drvsfs.c b/os/vfs/drivers/sfs/drvsfs.c index 0a293f1ef..3d616b108 100644 --- a/os/vfs/drivers/sfs/drvsfs.c +++ b/os/vfs/drivers/sfs/drvsfs.c @@ -67,7 +67,7 @@ static const struct vfs_sfs_driver_vmt driver_vmt = { }; static void *node_dir_addref(void *instance); -static void node_dir_release(void *instance); +static unsigned node_dir_release(void *instance); static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip); static msg_t node_dir_next(void *instance, vfs_direntry_info_t *dip); @@ -79,7 +79,7 @@ static const struct vfs_sfs_dir_node_vmt dir_node_vmt = { }; static void *node_file_addref(void *instance); -static void node_file_release(void *instance); +static unsigned node_file_release(void *instance); static BaseSequentialStream *node_file_get_stream(void *instance); static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n); @@ -215,14 +215,19 @@ static void *node_dir_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_dir_release(void *instance) { +static unsigned node_dir_release(void *instance) { vfs_sfs_dir_node_c *dnp = (vfs_sfs_dir_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_sfs_driver_static.dir_nodes_pool, (void *)dnp); } + + return references; } static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip) { @@ -256,14 +261,19 @@ static void *node_file_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_file_release(void *instance) { +static unsigned node_file_release(void *instance) { vfs_sfs_file_node_c *fnp = (vfs_sfs_file_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_sfs_driver_static.file_nodes_pool, (void *)fnp); } + + return references; } static BaseSequentialStream *node_file_get_stream(void *instance) { diff --git a/os/vfs/drivers/streams/drvstreams.c b/os/vfs/drivers/streams/drvstreams.c index f44d100f4..c032afc6f 100644 --- a/os/vfs/drivers/streams/drvstreams.c +++ b/os/vfs/drivers/streams/drvstreams.c @@ -69,7 +69,7 @@ static const struct vfs_streams_driver_vmt driver_vmt = { }; static void *node_dir_addref(void *instance); -static void node_dir_release(void *instance); +static unsigned node_dir_release(void *instance); static msg_t node_dir_getstat(void *instance, vfs_stat_t *sp); static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip); static msg_t node_dir_next(void *instance, vfs_direntry_info_t *dip); @@ -83,7 +83,7 @@ static const struct vfs_streams_dir_node_vmt dir_node_vmt = { }; static void *node_file_addref(void *instance); -static void node_file_release(void *instance); +static unsigned node_file_release(void *instance); static msg_t node_file_getstat(void *instance, vfs_stat_t *sp); static BaseSequentialStream *node_file_get_stream(void *instance); static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); @@ -277,14 +277,19 @@ static void *node_dir_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_dir_release(void *instance) { +static unsigned node_dir_release(void *instance) { vfs_streams_dir_node_c *sdnp = (vfs_streams_dir_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_streams_driver_static.dir_nodes_pool, (void *)sdnp); } + + return references; } static msg_t node_dir_getstat(void *instance, vfs_stat_t *sp) { @@ -327,14 +332,19 @@ static void *node_file_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_file_release(void *instance) { +static unsigned node_file_release(void *instance) { vfs_streams_file_node_c *sfnp = (vfs_streams_file_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_streams_driver_static.file_nodes_pool, (void *)sfnp); } + + return references; } static msg_t node_file_getstat(void *instance, vfs_stat_t *sp) { diff --git a/os/vfs/drivers/template/drvtemplate.c b/os/vfs/drivers/template/drvtemplate.c index ea5e51049..8ad363037 100644 --- a/os/vfs/drivers/template/drvtemplate.c +++ b/os/vfs/drivers/template/drvtemplate.c @@ -67,7 +67,7 @@ static const struct vfs_template_driver_vmt driver_vmt = { }; static void *node_dir_addref(void *instance); -static void node_dir_release(void *instance); +static unsigned node_dir_release(void *instance); static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip); static msg_t node_dir_next(void *instance, vfs_direntry_info_t *dip); @@ -79,7 +79,7 @@ static const struct vfs_template_dir_node_vmt dir_node_vmt = { }; static void *node_file_addref(void *instance); -static void node_file_release(void *instance); +static unsigned node_file_release(void *instance); static BaseSequentialStream *node_file_get_stream(void *instance); static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n); @@ -215,14 +215,19 @@ static void *node_dir_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_dir_release(void *instance) { +static unsigned node_dir_release(void *instance) { vfs_template_dir_node_c *dnp = (vfs_template_dir_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_template_driver_static.dir_nodes_pool, (void *)dnp); } + + return references; } static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip) { @@ -256,14 +261,19 @@ static void *node_file_addref(void *instance) { return __referenced_object_addref_impl(instance); } -static void node_file_release(void *instance) { +static unsigned node_file_release(void *instance) { vfs_template_file_node_c *fnp = (vfs_template_file_node_c *)instance; + unsigned references; - __referenced_object_release_impl(instance); - if (__referenced_object_getref_impl(instance) == 0U) { + chSysLock(); + references = __referenced_object_release_impl(instance); + chSysUnlock(); + if (references == 0U) { chPoolFree(&vfs_template_driver_static.file_nodes_pool, (void *)fnp); } + + return references; } static BaseSequentialStream *node_file_get_stream(void *instance) {