Skip to content
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

{EPOLL} Updated documentation after adding new API #873

Merged
merged 9 commits into from
Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 126 additions & 4 deletions docs/API-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ SRT API Functions
* [srt_epoll_add_usock, srt_epoll_add_ssock, srt_epoll_update_usock, srt_epoll_update_ssock](#srt_epoll_add_usock-srt_epoll_add_ssock-srt_epoll_update_usock-srt_epoll_update_ssock)
* [srt_epoll_remove_usock, srt_epoll_remove_ssock](#srt_epoll_remove_usock-srt_epoll_remove_ssock)
* [srt_epoll_wait](#srt_epoll_wait)
* [srt_epoll_uwait](#srt_epoll_uwait)
* [srt_epoll_set](#srt_epoll_set)
* [srt_epoll_release](#srt_epoll_release)
- [**Logging control**](#Logging-control)
* [srt_setloglevel](#srt_setloglevel)
Expand Down Expand Up @@ -1194,8 +1196,29 @@ these two calls.
* `eid`: epoll container id
* `u`: SRT socket
* `s`: system socket
* `events`: points to a variable set to epoll flags, or NULL if
you want to subscribe a socket for all possible events
* `events`: points to
* a variable set to epoll flags (see below) to use only selected events
* NULL if you want to subscribe a socket for all events in level-triggered mode

Epoll flags are bit flags that can be combined using `|` operator:
Copy link
Collaborator

Choose a reason for hiding this comment

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

'...combined into a mask"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This value is a mask, no matter if combined or a single flag is set. Maybe line 1200 should mention the "mask", at best.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please remove C language semantics, i.e. "using | operator"

* `SRT_EPOLL_IN`: report readiness for reading; (accept-readiness on listener socket)
* `SRT_EPOLL_OUT`: report readiness for writing (also connection succeeded)
* `SRT_EPOLL_ERR`: report error on the socket
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • SRT_EPOLL_IN: report readiness for reading or incoming connection on a listener socket
  • SRT_EPOLL_OUT: report readiness for writing or successful connection for a non-blocking socket
  • SRT_EPOLL_ERR: report errors on the socket

* `SRT_EPOLL_ET`: the event will be edge-triggered

Mind that the readiness states reported in epoll are by default
**level-triggered**, unless `SRT_EPOLL_ET` flag is specified, in which
case they are **edge-triggered**. Note that edge-triggered is only
supported for SRT sockets (to be fixed).
Copy link
Collaborator

Choose a reason for hiding this comment

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

The readiness states reported in by default are level-triggered. If
SRT_EPOLL_ET flag is specified, the reported states will become
edge-triggered. Note that at the time of this writing,
the edge-triggered mode is only supported for SRT sockets and not for regular
system sockets.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'd rather say simply "at this time". This might be fixed in future.


In the **edge-triggered** mode the function only returns socket states
which have changed since last call (that is, upon exit from the waiting
function any events reported there will be cleared in the internal flags
and therefore not reported in the next call, until the internals will
clear the state and set it again).
Copy link
Collaborator

Choose a reason for hiding this comment

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

In the edge-triggered mode, the function will only return socket states
that have changed since the last call. All events already reported will be
cleared in the internal flags and will not be reported again until
the internal signaling logic clears event report state and raises them again.


In the **level-triggered** mode the function will always return the
readiness state as long as it lasts, until the internals clear it.

- Returns:

Expand Down Expand Up @@ -1237,8 +1260,8 @@ int srt_epoll_wait(int eid, SRTSOCKET* readfds, int* rnum, SRTSOCKET* writefds,
```

Blocks the call until any readiness state occurs in the epoll container.
Mind that the readiness states reported in epoll are **permanent, not
edge-triggered**.
Mind that the readiness states reported in epoll are **permanent (level-
Copy link
Collaborator

Choose a reason for hiding this comment

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

Keep in mind that...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Damn, good that you pointed that out. This is no longer true. I'll fix accordingly.

triggered), not edge-triggered**.

Readiness can be on a socket in the container for the event type as per
subscription. The first readiness state causes this function to exit, but
Expand Down Expand Up @@ -1278,6 +1301,105 @@ of error has occurred on the socket.
This is reported only if `msTimeOut` was \>=0, otherwise the function waits
indefinitely.

### srt_epoll_uwait
```
int srt_epoll_uwait(int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut);
```

This function blocks a call until any readiness state occurs in the epoll
container. Unlike `srt_epoll_wait`, it can only be used with `eid` subscribed
to user sockets (SRT sockets), not system sockets.

This function blocks until the timeout. If timeout is 0, it exits
Copy link
Collaborator

Choose a reason for hiding this comment

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

The maximum duration of the call block is specified in milliseconds with the msTimeOut parameter.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The parameter definition precises the unit as milliseconds, although this name was worth adding.

immediately after checking. If timeout is -1, it blocks indefinitely
until a readiness state occurs.

* `eid`: epoll container
* `fdsSet` : A pointer to an array of `SRT_EPOLL_EVENT`
* `fdsSize` : The size of the fdsSet array
* `msTimeOut` : Timeout specified in milliseconds, or special values (0 or -1):
* 0: Don't wait, return immediately (report any sockets currently ready)
* -1: Wait indefinitely.

- Returns:

* The total amount of user socket (SRT socket) states changed. Note that this
can be larger than `fdsSize`, in this case and for events with `SRT_EPOLL_ET` flag
only `fdsSize` events are returned in the `fdsSet` and the remaining events can
be retrieved by a new call to this function
Copy link
Collaborator

Choose a reason for hiding this comment

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

The number of user socket (SRT socket) state changes that have been
placed in 'fdsSet' if that number is less or equal to fdsSize,
and fdsSize + 1 if that are more events than fdsSize. In all cases,
only the maximum of fdsSize events will be returned in the fdsSet array.
The remaining events can be retrieved by a new call to this function.


* 0, if no sockets were ready up to the timeout (never if waiting indefinitely)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Function has timed out

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Rephrased.


* -1 in case of error


- Errors:

* `SRT_EINVPOLLID`: `eid` designates no valid EID object
Copy link
Collaborator

Choose a reason for hiding this comment

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

Invalid 'eid' parameter

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This description is same in all other functions and it was approved previously by Steve. This can still be changed, but better one description be consistent for every function.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It is not the same in all other functions. For example, just below it is "eid parameter doesn't refer to a valid epoll container" and that is much better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Well, if so then all should be made the same then.

* `SRT_EINVPARAM`: One of possible usage errors:
* `fdsSize` is < 0
* `fdsSize` is > 0 and `fdsSet` is a null pointer
* `eid` was subscribed to any system socket

(IMPORTANT: this function reports timeout by returning 0, not by `SRT_ETIMEOUT` error.)

The `SRT_EPOLL_EVENT` structure:

```
typedef struct SRT_EPOLL_EVENT_
{
SRTSOCKET fd;
int events;
} SRT_EPOLL_EVENT;
```

* `fd` : the user socket (SRT socket)
* `events` : any combination of event flags:
* `SRT_EPOLL_IN`: ready for reading; listener socket ready to accept
* `SRT_EPOLL_OUT`: ready for writing; also connection succeeded
* `SRT_EPOLL_ERR`: error occurred on socket
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • SRT_EPOLL_IN: report readiness for reading or incoming connection on a listener socket
  • SRT_EPOLL_OUT: report readiness for writing or successful connection for a non-blocking socket
  • SRT_EPOLL_ERR: report errors on the socket

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Instead I removed all these descriptions and added reference to a function that described them previously.


Note that when the `SRT_EPOLL_ERR` is set the error cannot be retrieved
with `srt_getlasterror` but it means that the socket is closed and the
socket state can be read using `srt_getsockstate`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note that when the SRT_EPOLL_ERR is set, the underlying socket error
can't be retrieved with srt_getlasterror(). The socket will be automatically
closed and its state can be verified with a call to srt_getsockstate.


### srt_epoll_set
```
int32_t srt_epoll_set(int eid, int32_t flags);
```

Manipulate behavior flags. All default values for the flags are 0. You
can set appropriate flag in order to change the default behavior, or only
read the state of the current flags. The following flags are available:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This function allows settings appropriate flag in order to change the default behavior, reading the state of the current flags without modifying them.


* `SRT_EPOLL_ENABLE_EMPTY`: allows the `srt_epoll_wait` and `srt_epoll_uwait`
functions to be called with the EID not subscribed to any socket. By default,
if this function is called with EID not subscribed to any socket, it will
report an error
Copy link
Collaborator

Choose a reason for hiding this comment

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

The default behavior of these functions is to report an error if EID specified is not subscribed to any sockets.


* `SRT_EPOLL_ENABLE_OUTPUTCHECK`: Forces the `srt_epoll_wait` and `srt_epoll_uwait`
functions to check if the output array is not empty. For `srt_epoll_wait` it
is still allowed that either system or user array is empty, as long as EID
isn't subscribed to this type of socket/fd. For `srt_epoll_uwait` it's only
checked if the general output array is not empty.
Copy link
Collaborator

Choose a reason for hiding this comment

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

srt_epoll_uwait only checks if the general output array is not empty.


- Parameters:

* `eid`: the epoll container id
* `flags`: a nonzero set of the above flags, or special values:
* 0: clear all flags (set all defaults)
* -1: do not modify any flags

- Returns:

This function returns the state of the flags at the time before the call,
or a special value -1 in case when an error occurred.

- Errors:

* `SRT_EINVPOLLID`: eid parameter doesn't refer to a valid epoll container


### srt_epoll_release
```
int srt_epoll_release(int eid);
Expand Down
69 changes: 62 additions & 7 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,11 @@ Synopsis

int srt_epoll_update_usock(int eid, SRTSOCKET u, const int* events = NULL);
int srt_epoll_update_ssock(int eid, SYSSOCKET s, const int* events = NULL);

int srt_epoll_wait(int eid, SRTSOCKET* readfds, int* rnum, SRTSOCKET* writefds, int* wnum,
int64_t msTimeOut,
SYSSOCKET* lrfds, int* lrnum, SYSSOCKET* lwfds, int* lwnum);
int srt_epoll_uwait(int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut);


SRT Usage
---------
Expand All @@ -340,14 +344,65 @@ user-level epoll that supports both SRT and system sockets.
The `srt_epoll_update_{u|s}sock()` API functions described here are SRT additions
to the UDT-derived `srt_epoll_add_{u|s}sock()` and `epoll_remove_{u|s}sock()`
functions to atomically change the events of interest. For example, to remove
EPOLLOUT but keep EPOLLIN for a given socket with the existing API, the socket
must be removed from epoll and re-added. This cannot be done atomically, the
thread protection (against the epoll thread) being applied within each function
but unprotected between the two calls. It is then possible to lose a POLLIN
event if it fires while the socket is not in the epoll list.
`SRT_EPOLL_OUT` but keep `SRT_EPOLL_IN` for a given socket with the existing
API, the socket must be removed from epoll and re-added. This cannot be done
atomically, the thread protection (against the epoll thread) being applied
within each function but unprotected between the two calls. It is then possible
to lose an `SRT_EPOLL_IN` event if it fires while the socket is not in the
epoll list.

Once subscriptions are made, a waiting function can be called in order to
block the call commonly for all subscribed sockets together and exit from
waiting when the first one is ready. This can be waited up to the given timeout
in `[ms]`, with two special values:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Once subscriptions are made, an SRT polling function can be used to wait for
an event to be raised on any of the subscribed sockets. The polling functions
will exit as soon as at least one event is detected or a timeout occurs.
The timeout is specified in [ms], with two special values:


- 0: check and report immediately (don't wait)
- -1: wait indefinitely (also hangup until any event happens, not interruptable)
Copy link
Collaborator

Choose a reason for hiding this comment

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

-1: wait indefinitely (ignores system signals, not interruptable)


There are some differences in the synopsis between these two:

1. `srt_epoll_wait`: Both system and SRT sockets can be subscribed. This
function reports events on both socket types according to subscriptions, in
these arrays:

- `readfds` and `lrfds`: subscribed for `IN` and `ERR`
- `writefds` and `lwfds`: subscribed for `OUT` and `ERR`

where:

- `readfds` and `writefds` report SRT sockets ("user" socket)
- `lrfds` and `lwfds` report system sockets

Note: there's no separate place to report error. The only way to distinguish
error and in/out event is when you subscribe to `IN` or `OUT` only, and the
error then can be recognized by the fact that the socket appears in both arrays.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note: there's no separate array to report an error. Currently, the only way
to distinguish an error from an in/out event is to provide both,
readfds and writefds arrays and subscribe to ERR. The error can then
be recognized by the fact that the socket appears in both arrays.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I need to rephrase it as well. What you wrote here is also not exactly true - the trick is that if you subscribe a socket to both SRT_EPOLL_IN and SRT_EPOLL_OUT, there's no way to distinguish readiness for both at once and an error simultaneously. For example, if you subscribe to SRT_EPOLL_IN and SRT_EPOLL_ERR (but not OUT), erroneous sockets will appear in the writefds array.


This function also reports error of type `SRT_ETIMEOUT` when no socket is
ready as the timeout elapses (including 0).

Note that in this function there's a loop that checks for socket readiness
every 10ms. This waiting time can be shortened only for SRT sockets when
they become ready earlier after the previous check.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note that in this function there's a loop that checks for socket readiness
every 10ms. This, the minimum poll timeout the function can reliably support
is also 10ms. The return time from a poll function can only be quicker
when there is an event raised on one of the active SRT sockets.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You meant "thus", I believe :)


2. `srt_epoll_uwait`: In this function only the SRT sockets can be subscribed
(it reports error if you pass an epoll id that is subscribed to system sockets).
This function waits for the first event on subscribed SRT socket and reports all
events collected at this moment in an array of this structure:

```
typedef struct SRT_EPOLL_EVENT_
{
SRTSOCKET fd;
int events;
} SRT_EPOLL_EVENT;

```

Every item reports a single socket with all events as flags.


The SRT EPoll system does not supports all features of Linux epoll. For
example, it only supports level-triggered events.
example, it only supports level-triggered events for system sockets.

Options
=======
Expand Down