Skip to content

sock: initial definitions for asynchronous event handling#11723

Merged
miri64 merged 1 commit intoRIOT-OS:masterfrom
miri64:sock/enh/async2
Oct 30, 2019
Merged

sock: initial definitions for asynchronous event handling#11723
miri64 merged 1 commit intoRIOT-OS:masterfrom
miri64:sock/enh/async2

Conversation

@miri64
Copy link
Member

@miri64 miri64 commented Jun 19, 2019

Contribution description

This represents another approach to asynchronous sock as outlined in #8149 (comment). Apart from the necessary definitions for all basic sock types, this PR also contains example implementations for event.h and msg.h which can also be separated out into another PR.

Testing procedure

No implementation in this PR, just API (and a implementations using this unimplemented API ;-)).

Issues/PRs references

Alternative to #8149.

@miri64 miri64 added Area: network Area: Networking Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR Process: API change Integration Process: PR contains or issue proposes an API change. Should be handled with care. labels Jun 19, 2019
@miri64 miri64 requested a review from kaspar030 June 19, 2019 13:03
@miri64 miri64 added this to the Release 2019.10 milestone Jun 19, 2019
@kaspar030
Copy link
Contributor

Nice move forward!

Some thoughts (only brief look):

  • if we introduce a generic sock_t first, that all other sock types (udp, tcp, ip, ...) inherit from, the API gets a lot smaller, and the async handling part can be written once, for all of them. And IMO, as now we're starting to get shared funtionality, this would actually make sense to introduce.
    I'm envisioning only a couple of ops, like read(), write(), close(), status(), setup_async_event() .

  • the event type needs to be OR'ed.

If I see correctly, there's one "ctx" per sock, and thus one event object. If now there are multiple events (CAN_READ | CLOSED), the second that arrives overwrites the first. The event should be used as bitfield, and it should be set in a way that even if the event is already queued, a subsequent bit that gets set can still be read.

  • Do you think we need to go all generic with the callback method?

I think we might get away with just ifdef'ing support for the different event methods, without resorting to custom types.
Like, only #ifdef MODULE_SOCK_ASYNC_EVENT, the necessary fields are added to "sock_x_t", and the helper functions are included.

@miri64
Copy link
Member Author

miri64 commented Jun 19, 2019

  • if we introduce a generic sock_t first, that all other sock types (udp, tcp, ip, ...) inherit from, the API gets a lot smaller, and the async handling part can be written once, for all of them. And IMO, as now we're starting to get shared funtionality, this would actually make sense to introduce.
    I'm envisioning only a couple of ops, like read(), write(), close(), status(), setup_async_event() .

I was thinking about this, actually even had some header definitions for that however those were transparent to the lower levels of the implementation and thus did not really simplify things. Everything beyond that would rather be a completely new API, which would not sock and thus has nothing to do with my proposal.

  • the event type needs to be OR'ed.

They will be. By the lower level implementation. As you can see for sock_event_type_t, the values are OR'able ;-).

If I see correctly, there's one "ctx" per sock, and thus one event object.

ctx is very implementation specific, as you may have noticed, so it could also be a queue of objects.

If now there are multiple events (CAN_READ | CLOSED), the second that arrives overwrites the first. The event should be used as bitfield, and it should be set in a way that even if the event is already queued, a subsequent bit that gets set can still be read.

There are ways to prevent that (e.g. making sure the callback is only once and then again after an event was handled)

  • Do you think we need to go all generic with the callback method?

As pointed out above: I'm against changing the current API (apart from amendments and minor changes) at this point.

I think we might get away with just ifdef'ing support for the different event methods, without resorting to custom types.
Like, only #ifdef MODULE_SOCK_ASYNC_EVENT, the necessary fields are added to "sock_x_t", and the helper functions are included.

That is the idea of SOCK_HAS_ASYNC

@miri64
Copy link
Member Author

miri64 commented Jun 19, 2019

Another reason against using a "generic sock" here would be that it then wouldn't be applicable for TCP listener queues.

@miri64
Copy link
Member Author

miri64 commented Jun 19, 2019

I added another example implementation using msg_t which could come in handy at some point for fixing #8130

@haukepetersen
Copy link
Contributor

Very nice, can't wait to have axync sock!

I am not 100% sure if I understood the code correctly, but I don't like the direct mapping to event and msg. I would think that it is more flexible and future proof, if we would introduce a classical callback interface without any dependency to any IPC implemenation as base.

We can then use this 'lower-level' to implement the usual convenience wrappers for concrete IPC implementations (msg, event, thread_flags) on top of that, pretty much like the xtimer interface. This way we can easily map any IPC that might pop up in the future, but also users are able to decide on their own way to handle sock events... Also it makes it easy to select the needed functionality, as in 'USEMODULE sock_async_thread_flags` etc...

If this is already the case and I just did not read the code of this PR correctly then never mind :-)

@miri64
Copy link
Member Author

miri64 commented Oct 8, 2019

I am not 100% sure if I understood the code correctly, but I don't like the direct mapping to event and msg. I would think that it is more flexible and future proof, if we would introduce a classical callback interface without any dependency to any IPC implemenation as base.

There is no direct mapping to event and msg. The code mapping to event and msg are just example implementations of how to map the callback structure of async sock to RIOT... So what you are proposing is already the case here.

@miri64
Copy link
Member Author

miri64 commented Oct 8, 2019

See e.g. 8d33aed for how async sock is handled for sock_udp. If you want some thing more complicated and abstract than just callbacks, we can go back to #8149 but that was stalled for years...

@miri64
Copy link
Member Author

miri64 commented Oct 8, 2019

If this is already the case and I just did not read the code of this PR correctly then never mind :-)

Sorry, should have read your comment to the very end 😅. Yes, what you are proposing is already the case.

@haukepetersen
Copy link
Contributor

Now I saw, I mainly missed the difference of sock_event_type_t and sock_event_t :-)

@miri64
Copy link
Member Author

miri64 commented Oct 8, 2019

I gave this PR some well deserved love:

  • Rebased to current master
  • Added DTLS support
  • Made sure the sock_async_* modules are compilable ;-)

All that's missing is some doc on the sock_async_* modules IMHO and then it might be ready to go (of course the network stacks need to implement the event triggering as well, but that I rather would do as a follow-up).

@miri64
Copy link
Member Author

miri64 commented Oct 8, 2019

Added some doc for sock_async_event.

@miri64
Copy link
Member Author

miri64 commented Oct 8, 2019

OK. I updated all the doc now. Anybody wants to review. I did not test, if the examples I provide work, as there is no implementation of this API yet, but I'd be happy to provide one for GNRC and lwIP, once I get some positive feedback.

@miri64
Copy link
Member Author

miri64 commented Oct 8, 2019

If people prefer it, I can factor out the example front-end implementations into separate PRs.

@kb2ma kb2ma modified the milestones: Release 2019.10, Release 2020.01 Oct 9, 2019
@miri64
Copy link
Member Author

miri64 commented Oct 11, 2019

@haukepetersen @kaspar030 et al. can I please have some feedback on this?

ctx->event.sock = sock;
ctx->event.type |= type;
event_post(ctx->queue, &ctx->event.super);
ctx->event.type &= ~type;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this must stay set until after the cb has been executed.

@miri64
Copy link
Member Author

miri64 commented Oct 29, 2019

@kaspar030 and I discussed a bit about this online and we decided to take out the the front-end implementations for now for several reason:

  • To get this ahead and simplify the review
  • It is not clear if sock_async_msg makes sense at the moment
  • sock_async_event needs improvement
  • There is potential for a unified event handler that can be re-used by all front-end implementations.

As this needs some cherry-picking and reverting I will go ahead and squash everything.

@miri64
Copy link
Member Author

miri64 commented Oct 29, 2019

Squashed first (and renamed the event type flags as they caused some confusion offline)

@miri64
Copy link
Member Author

miri64 commented Oct 29, 2019

And squashed and renamed again (forgot to rename the usage of that type)

@miri64
Copy link
Member Author

miri64 commented Oct 29, 2019

Aand removed the implementations. Ready for review again.

@miri64
Copy link
Member Author

miri64 commented Oct 29, 2019

So they don't get lost, find the implementations in #12601 and #12602. I marked them as demonstrator (core_msg) and WIP (event) respectively, to mark their current state (core_msg not sure if want but provides an example, event needs some work).

@miri64
Copy link
Member Author

miri64 commented Oct 29, 2019

Pushed also some doc adaptions to be more in line with the new name.

* @note Only applicable with @ref SOCK_HAS_ASYNC defined.
*/
typedef enum {
SOCK_EVENT_CONN_RDY = 0x0001, /**< Connection ready event */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe SOCK_ASYNC_foo?


#if SOCK_HAS_ASYNC_CTX || defined(DOXYGEN)
/**
* @brief Gets the asynchronous
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

Copy link
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very promising!

We discussed offline that while this API is not stable we'll keep it separate from the existing sock headers and just copy all changes from this PR into a shared sock/async.h.
That way existing code, API and headers stay untouched for now.

@miri64
Copy link
Member Author

miri64 commented Oct 30, 2019

We discussed offline that while this API is not stable we'll keep it separate from the existing sock headers and just copy all changes from this PR into a shared sock/async.h.
That way existing code, API and headers stay untouched for now.

Done and squashed (as I removed most commits anyway).

Copy link
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK. Great starting point.

@kaspar030 kaspar030 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR Process: API change Integration Process: PR contains or issue proposes an API change. Should be handled with care. labels Oct 30, 2019
@miri64 miri64 merged commit 5b4b12e into RIOT-OS:master Oct 30, 2019
@miri64 miri64 deleted the sock/enh/async2 branch October 30, 2019 16:12
@miri64
Copy link
Member Author

miri64 commented Oct 30, 2019

Thanks for reviewing and getting this finally in!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants