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.
This commit is contained in:
Lennart Poettering 2013-04-04 18:31:22 +02:00
parent 60491a2869
commit 667c24a6a8
5 changed files with 92 additions and 11 deletions

View File

@ -48,6 +48,7 @@
<refname>sd_login_monitor_flush</refname>
<refname>sd_login_monitor_get_fd</refname>
<refname>sd_login_monitor_get_events</refname>
<refname>sd_login_monitor_get_timeout</refname>
<refname>sd_login_monitor</refname>
<refpurpose>Monitor login sessions, seats and users</refpurpose>
</refnamediv>
@ -82,6 +83,12 @@
<paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
</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>
</refsynopsisdiv>
@ -130,7 +137,9 @@
or a similar interface. The application should include
the returned file descriptor as wake-up source for the
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
reset via
<function>sd_login_monitor_flush()</function>. An
@ -146,15 +155,51 @@
and similar to fill into the
<literal>.events</literal> field of <literal>struct
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>
<title>Return Value</title>
<para>On success
<function>sd_login_monitor_new()</function> and
<function>sd_login_monitor_flush()</function> return 0
or a positive integer. On success
<function>sd_login_monitor_new()</function>,
<function>sd_login_monitor_flush()</function> and
<function>sd_login_monitor_get_timeout()</function>
return 0 or a positive integer. On success
<function>sd_login_monitor_get_fd()</function> returns
a Unix file descriptor. On success
<function>sd_login_monitor_get_events()</function>
@ -173,8 +218,9 @@
<para>The <function>sd_login_monitor_new()</function>,
<function>sd_login_monitor_unref()</function>,
<function>sd_login_monitor_flush()</function>,
<function>sd_login_monitor_get_fd()</function> and
<function>sd_login_monitor_get_events()</function>
<function>sd_login_monitor_get_fd()</function>,
<function>sd_login_monitor_get_events()</function> and
<function>sd_login_monitor_get_timeout()</function>
interfaces are available as shared library, which can
be compiled and linked to with the
<literal>libsystemd-login</literal>
@ -189,7 +235,8 @@
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</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>
</refsect1>

View File

@ -62,4 +62,5 @@ global:
LIBSYSTEMD_LOGIN_201 {
global:
sd_login_monitor_get_events;
sd_login_monitor_get_timeout;
} LIBSYSTEMD_LOGIN_198;

View File

@ -804,5 +804,23 @@ _public_ int sd_login_monitor_get_events(sd_login_monitor *m) {
if (!m)
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;
}
_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;
}

View File

@ -183,12 +183,23 @@ int main(int argc, char* argv[]) {
r = sd_login_monitor_new("session", &m);
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++) {
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);
sd_login_monitor_flush(m);

View File

@ -23,6 +23,7 @@
***/
#include <sys/types.h>
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
@ -159,6 +160,9 @@ int sd_login_monitor_get_fd(sd_login_monitor *m);
/* Get poll() mask to monitor */
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
}
#endif