summary refs log tree commit diff
path: root/docs/libnm/html/usage.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/libnm/html/usage.html')
-rw-r--r--docs/libnm/html/usage.html152
1 files changed, 131 insertions, 21 deletions
diff --git a/docs/libnm/html/usage.html b/docs/libnm/html/usage.html
index 1dbd66f4..c6404801 100644
--- a/docs/libnm/html/usage.html
+++ b/docs/libnm/html/usage.html
@@ -8,7 +8,7 @@
 <link rel="up" href="ref-overview.html" title="Overview">
 <link rel="prev" href="ref-overview.html" title="Overview">
 <link rel="next" href="ch02.html" title="Client Object API Reference">
-<meta name="generator" content="GTK-Doc V1.29.1 (XML mode)">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -73,18 +73,18 @@
 10
 11
 12</pre></td>
-        <td class="listing_code"><pre class="programlisting"><span class="cp">#include</span> <span class="cpf">&lt;glib.h&gt;</span><span class="cp"></span>
-<span class="cp">#include</span> <span class="cpf">&lt;NetworkManager.h&gt;</span><span class="cp"></span>
+        <td class="listing_code"><pre class="programlisting"><span class="preproc">#include</span><span class="normal"> </span><span class="string">&lt;glib.h&gt;</span>
+<span class="preproc">#include</span><span class="normal"> </span><span class="string">&lt;NetworkManager.h&gt;</span>
 
-<span class="kt">int</span>
-<span class="nf">main</span> <span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
-<span class="p">{</span>
-	<span class="n">NMClient</span> <span class="o">*</span><span class="n">client</span><span class="p">;</span>
+<span class="type">int</span>
+<span class="function">main</span><span class="normal"> </span><span class="symbol">(</span><span class="type">int</span><span class="normal"> argc</span><span class="symbol">,</span><span class="normal"> </span><span class="type">char</span><span class="normal"> </span><span class="symbol">*</span><span class="normal">argv</span><span class="symbol">[])</span>
+<span class="cbracket">{</span>
+<span class="normal">    </span><span class="usertype">NMClient</span><span class="normal"> </span><span class="symbol">*</span><span class="normal">client</span><span class="symbol">;</span>
 
-	<span class="n">client</span> <span class="o">=</span> <span class="n">nm_client_new</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
-	<span class="k">if</span> <span class="p">(</span><span class="n">client</span><span class="p">)</span>
-		<span class="n">g_print</span> <span class="p">(</span><span class="s">&quot;NetworkManager version: %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">nm_client_get_version</span> <span class="p">(</span><span class="n">client</span><span class="p">));</span>
-<span class="p">}</span></pre></td>
+<span class="normal">    client </span><span class="symbol">=</span><span class="normal"> </span><span class="function"><a href="NMClient.html#nm-client-new">nm_client_new</a></span><span class="normal"> </span><span class="symbol">(</span><span class="normal"><a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS">NULL</a></span><span class="symbol">,</span><span class="normal"> <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS">NULL</a></span><span class="symbol">);</span>
+<span class="normal">    </span><span class="keyword">if</span><span class="normal"> </span><span class="symbol">(</span><span class="normal">client</span><span class="symbol">)</span>
+<span class="normal">        </span><span class="function"><a href="https://developer.gnome.org/glib/unstable/glib-Warnings-and-Assertions.html#g-print">g_print</a></span><span class="normal"> </span><span class="symbol">(</span><span class="string">"NetworkManager version: %s</span><span class="specialchar">\n</span><span class="string">"</span><span class="symbol">,</span><span class="normal"> </span><span class="function"><a href="NMClient.html#nm-client-get-version">nm_client_get_version</a></span><span class="normal"> </span><span class="symbol">(</span><span class="normal">client</span><span class="symbol">));</span>
+<span class="cbracket">}</span></pre></td>
       </tr>
     </tbody>
   </table>
@@ -96,7 +96,7 @@
         </p>
 <pre class="screen"><code class="prompt">$ </code><strong class="userinput"><code>cc $(pkg-config --libs --cflags libnm) -o hello-nm hello-nm.c</code></strong>
   <code class="prompt">$ </code><strong class="userinput"><code>./hello-nm</code></strong>
-  NetworkManager version: 1.20.8
+  NetworkManager version: 1.22.0
 
   <code class="prompt">$ </code></pre>
 <p>
@@ -114,9 +114,9 @@
         <td class="listing_lines" align="right"><pre>1
 2
 3</pre></td>
-        <td class="listing_code"><pre class="programlisting"><span class="n">PKG_CHECK_MODULES</span><span class="p">(</span><span class="n">LIBNM</span><span class="p">,</span> <span class="n">libnm</span> <span class="o">&gt;=</span> <span class="mf">1.8</span><span class="p">)</span>
-<span class="n">LIBNM_CFLAGS</span><span class="o">=</span><span class="s">&quot;$LIBNM_CFLAGS -DNM_VERSION_MIN_REQUIRED=NM_VERSION_1_8&quot;</span>
-<span class="n">LIBNM_CFLAGS</span><span class="o">=</span><span class="s">&quot;$LIBNM_CFLAGS -DNM_VERSION_MAX_ALLOWED=NM_VERSION_1_8&quot;</span></pre></td>
+        <td class="listing_code"><pre class="programlisting"><span class="function">PKG_CHECK_MODULES</span><span class="symbol">(</span><span class="normal">LIBNM</span><span class="symbol">,</span><span class="normal"> libnm </span><span class="symbol">&gt;=</span><span class="normal"> </span><span class="number">1.8</span><span class="symbol">)</span>
+<span class="normal">LIBNM_CFLAGS</span><span class="symbol">=</span><span class="string">"$LIBNM_CFLAGS -DNM_VERSION_MIN_REQUIRED=NM_VERSION_1_8"</span>
+<span class="normal">LIBNM_CFLAGS</span><span class="symbol">=</span><span class="string">"$LIBNM_CFLAGS -DNM_VERSION_MAX_ALLOWED=NM_VERSION_1_8"</span></pre></td>
       </tr>
     </tbody>
   </table>
@@ -137,12 +137,12 @@
 4
 5
 6</pre></td>
-        <td class="listing_code"><pre class="programlisting"><span class="n">import</span> <span class="n">gi</span>
-<span class="n">gi</span><span class="p">.</span><span class="n">require_version</span><span class="p">(</span><span class="err">&#39;</span><span class="n">NM</span><span class="err">&#39;</span><span class="p">,</span> <span class="err">&#39;</span><span class="mf">1.0</span><span class="err">&#39;</span><span class="p">)</span>
-<span class="n">from</span> <span class="n">gi</span><span class="p">.</span><span class="n">repository</span> <span class="n">import</span> <span class="n">NM</span>
+        <td class="listing_code"><pre class="programlisting"><span class="normal">import gi</span>
+<span class="normal">gi</span><span class="symbol">.</span><span class="function">require_version</span><span class="symbol">(</span><span class="string">'NM'</span><span class="symbol">,</span><span class="normal"> </span><span class="string">'1.0'</span><span class="symbol">)</span>
+<span class="usertype">from</span><span class="normal"> gi</span><span class="symbol">.</span><span class="normal">repository import NM</span>
 
-<span class="n">client</span> <span class="o">=</span> <span class="n">NM</span><span class="p">.</span><span class="n">Client</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">None</span><span class="p">)</span>
-<span class="n">print</span> <span class="p">(</span><span class="s">&quot;NetworkManager version &quot;</span> <span class="o">+</span> <span class="n">client</span><span class="p">.</span><span class="n">get_version</span><span class="p">())</span></pre></td>
+<span class="normal">client </span><span class="symbol">=</span><span class="normal"> NM</span><span class="symbol">.</span><span class="normal">Client</span><span class="symbol">.</span><span class="function">new</span><span class="symbol">(</span><span class="normal">None</span><span class="symbol">)</span>
+<span class="function">print</span><span class="normal"> </span><span class="symbol">(</span><span class="string">"NetworkManager version "</span><span class="normal"> </span><span class="symbol">+</span><span class="normal"> client</span><span class="symbol">.</span><span class="function">get_version</span><span class="symbol">())</span></pre></td>
       </tr>
     </tbody>
   </table>
@@ -159,8 +159,118 @@
           <a class="ulink" href="https://gitlab.freedesktop.org/NetworkManager/NetworkManager/tree/master/examples" target="_top">some examples</a>.
         </p>
 </div>
+<div class="simplesect">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="sync-api"></a>Synchronous API in libnm</h3></div></div></div>
+<p>
+          Libnm contains some synchronous API. This API basically makes a blocking
+          D-Bus call (g_dbus_connection_call_sync()) and is now deprecated.
+        </p>
+<p>
+          Note that D-Bus is fundamentally asynchronous. Doing blocking calls
+          on top of D-Bus is odd, especially for libnm's NMClient. That is because
+          NMClient essentially is a client-side cache of the objects of the D-Bus
+          interface. This cache should be filled exclusively by (asynchronous) D-Bus
+          events. So, making a blocking D-Bus call means to wait for a response and
+          return it, while queuing everything that happens in between. Basically,
+          there are three options how a synchronous API on NMClient could behave:
+          </p>
+<div class="orderedlist"><ol class="orderedlist" type="1">
+<li class="listitem"><p>
+                The call basically calls g_dbus_connection_call_sync(). This means
+                that libnm sends a D-Bus request via GDBusConnection, and blockingly
+                waits for the response. All D-Bus messages that get received in the
+                meantime are queued in the GMainContext that belongs to NMClient.
+                That means, none of these D-Bus events are processed until we
+                iterate the GMainContext after the call returns. The effect is,
+                that NMClient (and all cached objects in there) are unaffected by
+                the D-Bus request.
+                Most of the synchronous API calls in libnm are of this kind.
+                The problem is that the strict ordering of D-Bus events gets
+                violated.
+                For some API this is not an immediate problem. Take for example
+                nm_device_wifi_request_scan(). The call merely blockingly tells
+                NetworkManager to start scanning, but since NetworkManager's D-Bus
+                API does not directly expose any state that tells whether we are
+                currently scanning, this out of order processing of the D-Bus
+                request is a small issue.
+                The problem is more obvious for nm_client_networking_set_enabled().
+                After calling it, NM_CLIENT_NETWORKING_ENABLED is still unaffected
+                and unchanged, because the PropertiesChanged signal from D-Bus
+                is not yet processed.
+                This means, while you make such a blocking call, NMClient's state
+                does not change. But usually you perform the synchronous call
+                to change some state. In this form, the blocking call is not useful,
+                because NMClient only changes the state after iterating the GMainContext,
+                and not after the blocking call returns.
+              </p></li>
+<li class="listitem"><p>
+                Like 1), but after making the blocking g_dbus_connection_call_sync(),
+                update the NMClient cache artificially. This is what
+                nm_manager_check_connectivity() does, to "fix" bgo#784629.
+                This also has the problem of out-of-order events, but it kinda
+                solves the problem of not changing the state during the blocking
+                call. But it does so by hacking the state of the cache. I think
+                this is really wrong because the state should only be updated from
+                the ordered stream of D-Bus messages. When libnm decides to modify
+                the state, there are already D-Bus messages queued that affect this
+                very state.
+              </p></li>
+<li class="listitem"><p>
+                Instead of calling g_dbus_connection_call_sync(), use the
+                asynchronous g_dbus_connection_call(). If we would use a sepaate
+                GMainContext for all D-Bus related calls, we could ensure that
+                while we block for the response, we iterate the internal main context.
+                This might be nice, because all events are processed in order and
+                after the blocking call returns, the NMClient state is up to date.
+                The are problems however: current blocking API does not do this,
+                so it's a significant change in behavior. Also, it might be
+                unexpected to the user that during the blocking call the entire
+                content of NMClient's cache might change and all pointers to the
+                cache might be invalidated. Also, of course NMClient would invoke
+                signals for all the changes that happen.
+                Another problem is that this would be more effort to implement
+                and it involves a small performance overhead for all D-Bus related
+                calls (because we have to serialize all events in an internal
+                GMainContext first and then invoke them on the caller's context).
+                Also, if the users wants this, they could implement it themself
+                using their own extra GMainContext and the asynchronous API.
+              </p></li>
+</ol></div>
+<p>
+
+          See also <a class="ulink" href="https://smcv.pseudorandom.co.uk/2008/11/nonblocking/" target="_top">this blog</a>
+          for why blocking calls are wrong.
+        </p>
+<p>
+          All possible behaviors for synchronous API have severe behavioural
+          issues and thus such API is deprecated. Note that "deprecated" here does not
+          mean that the API is going to be removed. Libnm does not break API. The
+          user may:
+
+          </p>
+<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<li class="listitem"><p>
+                Continue to use this API. It's deprecated, awkward and discouraged,
+                but if it works for you, that's fine.
+              </p></li>
+<li class="listitem"><p>
+                Use asynchronous API. That's the only sensible way to use D-Bus.
+                If libnm lacks a certain asynchronous counterpart, it should be
+                added.
+              </p></li>
+<li class="listitem"><p>
+                Use GDBusConnection directly. There really isn't anything wrong
+                with D-Bus or GDBusConnection. This deprecated API is just a wrapper
+                around g_dbus_connection_call_sync(). You may call it directly
+                without feeling dirty.
+              </p></li>
+</ul></div>
+<p>
+        </p>
+</div>
 </div>
 <div class="footer">
-<hr>Generated by GTK-Doc V1.29.1</div>
+<hr>Generated by GTK-Doc V1.29</div>
 </body>
 </html>
\ No newline at end of file