-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #540, add event callback framework #541
Fix #540, add event callback framework #541
Conversation
marked as "ccb ready" for concept/architecture discussion (not for merge yet). |
src/os/inc/osapi-os-core.h
Outdated
* @param[inout] data An abstract data/context object associated with the event, or NULL. | ||
* @return status Execution status, see @ref OSReturnCodes. | ||
*/ | ||
typedef int32 (*OS_EventHandler_t)(OS_Event_t event, uint32 object_id, void *data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
confused by the flow of the "data" void *. Usu. with a callback architecture, the opaque data is passed in by the registration and passed through as another "in" to the callback function pointer. But the registration does not define the opaque and this is defined as in/out? (Which implies that the caller would want/need to understand the contents of the data buffer.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(may be a good opportunity to draw up a sequence diagram or some other way to describe the flow of control and data handoffs.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The usage of the "data" opaque pointer field would be indicated by the event ID. Currently the set of events I've predefined don't use this, and all events pass the field as NULL. But there could be events that pass additional context info via this field, such as the object name. OR - it could be used for inputs, so the event could pass a buffer which is filled/set by the handler.
Again, right now the presence of this field is more of a "future-proof" item - to offer a way to include additional context if necessary without having to change the API in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chris has a good point. This should be some context registered with the handler and passed back to it. The concept you're talking about with using it for extra event parameters is going to lead to you having to either force the user to typecast in their callback or create a set of API functions to make the opaque data useful.
Also would like consideration how this might play with the OSAL "object id" framework. (And currently threads/tasks do not use the object id framework...which it should!) It might make sense that all "objects" would have this capability. |
CCB-2020-07-15: Good architecture, conversation about whether this is the appropriate way to solve the request in #533 |
@acudmore and @jwilmot thoughts? |
Not sure what you mean by "currently threads/tasks do not use the object id framework" .. can you elaborate? Everything does use the object ID framework, including tasks. |
Update - this PR here has some cleanup around the deletion of objects that would be nice to have for other reasons. IIRC it was discussed/reviewed in CCB a while back and there were no objections. @astrogeco - Can this be merged? If still on the fence about the callback structure, then if ncessary I can split it into a separate PR which consolidates the deletion/cleanup code (which I would like to have merged) and the callback bits. |
Did we want to get a review by either of the architects? |
Maybe @jwilmot and @klystron78. They have a potential to take advantage of this for the SMP work. |
@jphickey let's split this into two PRs so we can accelerate merging the callback stuff. |
* @retval #OS_SUCCESS @copybrief OS_SUCCESS | ||
* @retval #OS_ERROR @copybrief OS_ERROR | ||
*/ | ||
int32 OS_RegisterEventHandler (OS_EventHandler_t handler); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense to have a bitmask so the caller can specify which events are of interest. This idea also scales forward as more events are added. It could be 32-bit or 64-bit number which gives that many extra bits for future use. Perhaps 0 means "all events."
* The event handler is an application-defined callback | ||
* that gets invoked as resources are created/configured/deleted. | ||
*/ | ||
OS_EventHandler_t EventHandler; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can there only be one? It might be useful to follow the observer/observable pattern and have a list of observers, so that apps can monitor events as well to get an idea of the state of the system. I am not fully briefed on the use-case for this work, so this thought may be beyond scope.
src/os/shared/src/osapi-binsem.c
Outdated
@@ -157,14 +157,8 @@ int32 OS_BinSemDelete (uint32 sem_id) | |||
{ | |||
return_code = OS_BinSemDelete_Impl(local_id); | |||
|
|||
/* Free the entry in the master table now while still locked */ | |||
if (return_code == OS_SUCCESS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return_code is set on line 158 and not checked with this deletion. It's set again on 161.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return code is checked inside the OS_ObjectIdFinalizeDelete
function. There is cleanup to do for both success and failure cases. (This is a mirror image of the way the allocation/creation works too).
*-----------------------------------------------------------------*/ | ||
int32 OS_RegisterEventHandler (OS_EventHandler_t handler) | ||
{ | ||
if (handler == NULL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it an error if null is passed in? The effect would be to say "I am no longer interested in notifications," which seems like would not be an error.
src/os/shared/src/osapi-countsem.c
Outdated
@@ -150,14 +150,8 @@ int32 OS_CountSemDelete (uint32 sem_id) | |||
{ | |||
return_code = OS_CountSemDelete_Impl(local_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like before, return_code is set and not checked. It's set again on 154.
src/os/shared/src/osapi-dir.c
Outdated
@@ -187,14 +187,8 @@ int32 OS_DirectoryClose(uint32 dir_id) | |||
{ | |||
return_code = OS_DirClose_Impl(local_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
src/os/shared/src/osapi-file.c
Outdated
@@ -223,14 +223,8 @@ int32 OS_close (uint32 filedes) | |||
{ | |||
return_code = OS_GenericClose_Impl(local_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
src/os/shared/src/osapi-module.c
Outdated
@@ -289,14 +289,8 @@ int32 OS_ModuleUnload ( uint32 module_id ) | |||
*/ | |||
return_code = OS_ModuleUnload_Impl(local_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same thing with return_code set and then not checked, and set again below
src/os/shared/src/osapi-mutex.c
Outdated
@@ -145,14 +145,8 @@ int32 OS_MutSemDelete (uint32 sem_id) | |||
{ | |||
return_code = OS_MutSemDelete_Impl(local_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same thing with return_code set and then not checked, and set again below
src/os/shared/src/osapi-queue.c
Outdated
@@ -156,14 +156,8 @@ int32 OS_QueueDelete (uint32 queue_id) | |||
{ | |||
return_code = OS_QueueDelete_Impl(local_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same thing with return_code set and then not checked, and set again below
src/os/shared/src/osapi-task.c
Outdated
} | ||
|
||
/* | ||
** Call the thread Delete hook if there is one. | ||
*/ | ||
if (delete_hook != NULL) | ||
if (return_code == OS_SUCCESS && delete_hook != NULL) | ||
{ | ||
delete_hook(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need both delete hook and event for deletion?
src/os/shared/src/osapi-timebase.c
Outdated
@@ -260,14 +260,8 @@ int32 OS_TimeBaseDelete(uint32 timer_id) | |||
{ | |||
return_code = OS_TimeBaseDelete_Impl(local_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same thing with return_code set and then not checked, and set again below
c0b790c
to
c0bb696
Compare
c0bb696
to
51ac344
Compare
Note to reviewers - the initial use case for this callback is in #532, which requires invoking a Linux-specific API to set the name of the task. It is not intended for dynamic application level use - it is intended more as an extension mechanism to replace what would otherwise be platform-specific If we wanted to provide a more generic application-level callback - then yes I agree with the comments regarding providing a method to subscribe to only certain events, and providing another application-provided object to pair with the callback, and so forth. But that wasn't really the objective here. We can certainly do that if folks think its useful, but I don't really see the use-case for it right now. The singlular BSP/PSP-provided callback proposed here is much simpler to implement, as any dynamic registration/unregistration would be much more involved i.e. it would have to maintain a list, proper locking to support being invoked by any thread, etc. |
Need a path to closure, marking for review (unless we can reach consensus before CCB). |
CCB 2020-09-23 rebase on main and revisit on 2020-09-30. @acudmore and @CDKnightNASA will examine |
Define an interface to allow an app/PSP to be notified when state changes or other events occur at the OS level. Initially defined events are resource creation/deletion and task startup. The interface is easily extendable with more events as needed. This can be used to add platform-specific/nonstandard functions by putting the code inside the event handler at the PSP level.
51ac344
to
ba0448a
Compare
Rebased to latest main branch. Ready for (re-)review. Also see the use-case example at nasa/PSP@main...jphickey:jph-wip-linux-event-handler I have confirmed that when running this on my linux box with the change above applied, then the |
CCB 2020-09-30: APPROVED |
Describe the contribution
Adds an event callback mechanism to certain state changes in OSAL. This allows the CFE PSP to be notified at these points, and therefore it can add platform-specific functionality. This can, for instance, set the task name as requested in #532 or set the processor affinity in a multi-core setup (TBD).
Fixes #540
Testing performed
Create an event handler in the pc-linux CFE PSP and register it, and print out each event received. Confirm events are generated as expected, and that it didn't break the FSW in any way.
Note - Not completely tested yet -- this is mainly a proof of concept and pushed for design review at this time.
Expected behavior changes
Adds ability to implement custom platform-specific functionality for defined events.
System(s) tested on
Ubuntu 20.04
Additional context
Previous discussion in #532.
Contributor Info - All information REQUIRED for consideration of pull request
Joseph Hickey, Vantage Systems, Inc.