chiark / gitweb /
login: add sd_login_monitor_get_timeout() public api call
authorLennart Poettering <lennart@poettering.net>
Thu, 4 Apr 2013 16:31:22 +0000 (18:31 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 4 Apr 2013 16:31:22 +0000 (18:31 +0200)
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.

man/sd_login_monitor_new.xml
src/login/libsystemd-login.sym
src/login/sd-login.c
src/login/test-login.c
src/systemd/sd-login.h

index 9442877..b187ad0 100644 (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>
                                 <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>
 
                 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
                 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>
                 <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>
                         <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>
 
index 55a8287..ce2304a 100644 (file)
@@ -62,4 +62,5 @@ global:
 LIBSYSTEMD_LOGIN_201 {
 global:
         sd_login_monitor_get_events;
+        sd_login_monitor_get_timeout;
 } LIBSYSTEMD_LOGIN_198;
index 861a571..7513f76 100644 (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;
+}
index f639129..e4d0c93 100644 (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);
index 57255bd..d05424d 100644 (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