Commit 667c24a6 authored by Lennart Poettering's avatar Lennart Poettering

login: add sd_login_monitor_get_timeout() public api call

We don't need this right now, but we should keep our options open, in
case we need more than just an fd for waking up.
parent 60491a28
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
<refname>sd_login_monitor_flush</refname> <refname>sd_login_monitor_flush</refname>
<refname>sd_login_monitor_get_fd</refname> <refname>sd_login_monitor_get_fd</refname>
<refname>sd_login_monitor_get_events</refname> <refname>sd_login_monitor_get_events</refname>
<refname>sd_login_monitor_get_timeout</refname>
<refname>sd_login_monitor</refname> <refname>sd_login_monitor</refname>
<refpurpose>Monitor login sessions, seats and users</refpurpose> <refpurpose>Monitor login sessions, seats and users</refpurpose>
</refnamediv> </refnamediv>
...@@ -82,6 +83,12 @@ ...@@ -82,6 +83,12 @@
<paramdef>sd_login_monitor* <parameter>m</parameter></paramdef> <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
</funcprototype> </funcprototype>
<funcprototype>
<funcdef>int <function>sd_login_monitor_get_timeout</function></funcdef>
<paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
<paramdef>uint64_t* <parameter>timeout_usec</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -130,7 +137,9 @@ ...@@ -130,7 +137,9 @@
or a similar interface. The application should include or a similar interface. The application should include
the returned file descriptor as wake-up source for the the returned file descriptor as wake-up source for the
events mask returned by events mask returned by
<function>sd_login_monitor_get_events()</function>. Whenever <function>sd_login_monitor_get_events()</function>. It
should pass a timeout value as returned by
<function>sd_login_monitor_get_timeout()</function>. Whenever
a wake-up is triggered the file descriptor needs to be a wake-up is triggered the file descriptor needs to be
reset via reset via
<function>sd_login_monitor_flush()</function>. An <function>sd_login_monitor_flush()</function>. An
...@@ -146,15 +155,51 @@ ...@@ -146,15 +155,51 @@
and similar to fill into the and similar to fill into the
<literal>.events</literal> field of <literal>struct <literal>.events</literal> field of <literal>struct
pollfd</literal>.</para> pollfd</literal>.</para>
<para><function>sd_login_monitor_get_timeout()</function>
will return a timeout value for usage in
<function>poll()</function>. This returns a value in
microseconds since the epoch of CLOCK_MONOTONIC for
timing out <function>poll()</function> in
<literal>timeout_usec</literal>. See
<citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>
for details about
<literal>CLOCK_MONOTONIC</literal>. If there's no
timeout to wait for this will fill in
<literal>(uint64_t) -1</literal> instead. Note that
<function>poll()</function> takes a relative timeout
in milliseconds rather than an absolute timeout in
microseconds. To convert the absolute 'us' timeout into
relative 'ms', use code like the following:</para>
<programlisting>uint64_t t;
int msec;
sd_login_monitor_get_timeout(m, &amp;t);
if (t == (uint64_t) -1)
msec = -1;
else {
struct timespec ts;
uint64_t n;
clock_getttime(CLOCK_MONOTONIC, &amp;ts);
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
}</programlisting>
<para>The code above does not do any error checking
for brevity's sake. The calculated <literal>msec</literal>
integer can be passed directly as
<function>poll()</function>'s timeout
parameter.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>Return Value</title> <title>Return Value</title>
<para>On success <para>On success
<function>sd_login_monitor_new()</function> and <function>sd_login_monitor_new()</function>,
<function>sd_login_monitor_flush()</function> return 0 <function>sd_login_monitor_flush()</function> and
or a positive integer. On success <function>sd_login_monitor_get_timeout()</function>
return 0 or a positive integer. On success
<function>sd_login_monitor_get_fd()</function> returns <function>sd_login_monitor_get_fd()</function> returns
a Unix file descriptor. On success a Unix file descriptor. On success
<function>sd_login_monitor_get_events()</function> <function>sd_login_monitor_get_events()</function>
...@@ -173,8 +218,9 @@ ...@@ -173,8 +218,9 @@
<para>The <function>sd_login_monitor_new()</function>, <para>The <function>sd_login_monitor_new()</function>,
<function>sd_login_monitor_unref()</function>, <function>sd_login_monitor_unref()</function>,
<function>sd_login_monitor_flush()</function>, <function>sd_login_monitor_flush()</function>,
<function>sd_login_monitor_get_fd()</function> and <function>sd_login_monitor_get_fd()</function>,
<function>sd_login_monitor_get_events()</function> <function>sd_login_monitor_get_events()</function> and
<function>sd_login_monitor_get_timeout()</function>
interfaces are available as shared library, which can interfaces are available as shared library, which can
be compiled and linked to with the be compiled and linked to with the
<literal>libsystemd-login</literal> <literal>libsystemd-login</literal>
...@@ -189,7 +235,8 @@ ...@@ -189,7 +235,8 @@
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry> <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
<citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>
</para> </para>
</refsect1> </refsect1>
......
...@@ -62,4 +62,5 @@ global: ...@@ -62,4 +62,5 @@ global:
LIBSYSTEMD_LOGIN_201 { LIBSYSTEMD_LOGIN_201 {
global: global:
sd_login_monitor_get_events; sd_login_monitor_get_events;
sd_login_monitor_get_timeout;
} LIBSYSTEMD_LOGIN_198; } LIBSYSTEMD_LOGIN_198;
...@@ -804,5 +804,23 @@ _public_ int sd_login_monitor_get_events(sd_login_monitor *m) { ...@@ -804,5 +804,23 @@ _public_ int sd_login_monitor_get_events(sd_login_monitor *m) {
if (!m) if (!m)
return -EINVAL; return -EINVAL;
/* For now we will only return POLLIN here, since we don't
* need anything else ever for inotify. However, let's have
* this API to keep our options open should we later on need
* it. */
return POLLIN; return POLLIN;
} }
_public_ int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec) {
if (!m)
return -EINVAL;
if (!timeout_usec)
return -EINVAL;
/* For now we will only return (uint64_t) -1, since we don't
* need any timeout. However, let's have this API to keep our
* options open should we later on need it. */
*timeout_usec = (uint64_t) -1;
return 0;
}
...@@ -183,12 +183,23 @@ int main(int argc, char* argv[]) { ...@@ -183,12 +183,23 @@ int main(int argc, char* argv[]) {
r = sd_login_monitor_new("session", &m); r = sd_login_monitor_new("session", &m);
assert_se(r >= 0); assert_se(r >= 0);
zero(pollfd);
pollfd.fd = sd_login_monitor_get_fd(m);
pollfd.events = sd_login_monitor_get_events(m);
for (n = 0; n < 5; n++) { for (n = 0; n < 5; n++) {
r = poll(&pollfd, 1, -1); usec_t timeout, nw;
zero(pollfd);
assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0);
assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0);
assert_se(sd_login_monitor_get_timeout(m, &timeout) >= 0);
nw = now(CLOCK_MONOTONIC);
r = poll(&pollfd, 1,
timeout == (uint64_t) -1 ? -1 :
timeout > nw ? (int) ((timeout - nw) / 1000) :
0);
assert_se(r >= 0); assert_se(r >= 0);
sd_login_monitor_flush(m); sd_login_monitor_flush(m);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
***/ ***/
#include <sys/types.h> #include <sys/types.h>
#include <inttypes.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
...@@ -159,6 +160,9 @@ int sd_login_monitor_get_fd(sd_login_monitor *m); ...@@ -159,6 +160,9 @@ int sd_login_monitor_get_fd(sd_login_monitor *m);
/* Get poll() mask to monitor */ /* Get poll() mask to monitor */
int sd_login_monitor_get_events(sd_login_monitor *m); int sd_login_monitor_get_events(sd_login_monitor *m);
/* Get timeout for poll(), as usec value relative to CLOCK_MONOTONIC's epoch */
int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment