[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Wed Jun 12 11:55:02 MDT 2013


The branch, master has been updated
       via  d6ce140 tevent: Link the tutorial on the mainpage.
       via  1bce251 tevent: Add tevent tutorial files.
      from  7bad9d1 s3-libads: Print the debug string of a failed call with LDAP_OTHER.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d6ce1402a964858bf40b23f34df01f1f01839d3a
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jun 12 13:55:13 2013 +0200

    tevent: Link the tutorial on the mainpage.
    
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Wed Jun 12 19:54:30 CEST 2013 on sn-devel-104

commit 1bce2510ca9a2eec20f2a32499f0839b768f7c4a
Author: David Koňař <konar.david at gmail.com>
Date:   Wed Jun 12 13:54:36 2013 +0200

    tevent: Add tevent tutorial files.
    
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/tevent/doc/img/tevent_context_stucture.png |  Bin 0 -> 21888 bytes
 lib/tevent/doc/img/tevent_subrequest.png       |  Bin 0 -> 22453 bytes
 lib/tevent/doc/mainpage.dox                    |   11 +-
 lib/tevent/doc/tevent_context.dox              |   75 +++
 lib/tevent/doc/tevent_data.dox                 |  133 +++++
 lib/tevent/doc/tevent_events.dox               |  341 ++++++++++++
 lib/tevent/doc/tevent_queue.dox                |  274 ++++++++++
 lib/tevent/doc/tevent_request.dox              |  191 +++++++
 lib/tevent/doc/tevent_tutorial.dox             |   20 +
 lib/tevent/doxy.config                         |  681 ++++++++++++++++++------
 10 files changed, 1569 insertions(+), 157 deletions(-)
 create mode 100644 lib/tevent/doc/img/tevent_context_stucture.png
 create mode 100644 lib/tevent/doc/img/tevent_subrequest.png
 create mode 100644 lib/tevent/doc/tevent_context.dox
 create mode 100644 lib/tevent/doc/tevent_data.dox
 create mode 100644 lib/tevent/doc/tevent_events.dox
 create mode 100644 lib/tevent/doc/tevent_queue.dox
 create mode 100644 lib/tevent/doc/tevent_request.dox
 create mode 100644 lib/tevent/doc/tevent_tutorial.dox


Changeset truncated at 500 lines:

diff --git a/lib/tevent/doc/img/tevent_context_stucture.png b/lib/tevent/doc/img/tevent_context_stucture.png
new file mode 100644
index 0000000..fba8161
Binary files /dev/null and b/lib/tevent/doc/img/tevent_context_stucture.png differ
diff --git a/lib/tevent/doc/img/tevent_subrequest.png b/lib/tevent/doc/img/tevent_subrequest.png
new file mode 100644
index 0000000..ea79223
Binary files /dev/null and b/lib/tevent/doc/img/tevent_subrequest.png differ
diff --git a/lib/tevent/doc/mainpage.dox b/lib/tevent/doc/mainpage.dox
index e2f986e..5b76013 100644
--- a/lib/tevent/doc/mainpage.dox
+++ b/lib/tevent/doc/mainpage.dox
@@ -10,13 +10,18 @@
  * Tevent also provide helpers to deal with asynchronous code providing the
  * tevent_req (tevent request) functions.
  *
- * @section tevent_download Download
+ * @section main_tevent_tutorial Tutorial
+ *
+ * You should start by reading @subpage tevent_tutorial, then reading the
+ * documentation of the interesting functions as you go.
+ *
+ * @section main_tevent_download Download
  *
  * You can download the latest releases of tevent from the
  * <a href="http://samba.org/ftp/tevent" target="_blank">tevent directory</a>
  * on the samba public source archive.
  *
- * @section tevent_bugs Discussion and bug reports
+ * @section main_tevent_bugs Discussion and bug reports
  *
  * tevent does not currently have its own mailing list or bug tracking system.
  * For now, please use the
@@ -25,7 +30,7 @@
  * <a href="http://bugzilla.samba.org/" target="_blank">Samba bugzilla</a>
  * bug tracking system.
  *
- * @section tevent_devel Development
+ * @section main_tevent_devel Development
  * You can download the latest code either via git or rsync.
  *
  * To fetch via git see the following guide:
diff --git a/lib/tevent/doc/tevent_context.dox b/lib/tevent/doc/tevent_context.dox
new file mode 100644
index 0000000..1036d3c
--- /dev/null
+++ b/lib/tevent/doc/tevent_context.dox
@@ -0,0 +1,75 @@
+/**
+ at page tevent_context Chapter 1: Tevent context
+
+ at section context Tevent context
+
+Tevent context is an essential logical unit of tevent library. For working with
+events at least one such context has to be created - allocated, initialized.
+Then, events which are meant to be caught and handled have to be registered
+within this specific context. Reason for subordinating events to a tevent
+context structure rises from the fact that several context can be created and
+each of them is processed at different time. So, there can be 1 context
+containing just file descriptor events, another one taking care of signal and
+time events and the third one which keeps information about the rest.
+
+Tevent loops are the part of the library which represents the mechanism where
+noticing events and triggering handlers actually happens. They accept just one
+argument - tevent context structure. Therefore if theoretically an infinity
+loop (tevent_loop_wait) was called, only those arguments which belong to the
+passed tevent context structure can be caught and invoked within this call.
+Although some more signal events were registered (but within some other
+context) they will not be noticed.
+
+ at subsection Example
+
+First lines which handle <code>mem_ctx</code> belong to talloc library
+knowledge but because of the fact that tevent uses the talloc library for its
+mechanisms it is necessary to understand a bit talloc as well. For more
+information about working with talloc, please visit <a
+href="http://talloc.samba.org/">talloc website</a> where tutorial and
+documentation are located.
+
+Tevent context structure <code>*event_ctx</code> represents the unit which will
+further contain information about registered events. It is created via calling
+tevent_context_init().
+
+ at code
+TALLOC_CTX *mem_ctx = talloc_new(NULL);
+if (mem_ctx == NULL) {
+    // error handling
+}
+
+struct tevent_context *ev_ctx = tevent_context_init(mem_ctx);
+if(ev_ctx == NULL) {
+    // error handling
+}
+ at endcode
+
+Tevent context has a structure containing lots of information. It include lists
+of all events which are divided according their type and are in order showing
+the sequence as they came.
+
+ at image html tevent_context_stucture.png
+
+In addition to the lists shown in the diagram, the tevent context also contains
+many other data (e.g. information about the available system mechanism for
+triggering callbacks).
+
+ at section tevent_loops Tevent loops
+
+Tevent loops are the dispatcher for events. They catch them and trigger the
+handlers. In the case of longer processes, the program spends most of its time
+at this point waiting for events, invoking handlers and waiting for another
+event again. There are 2 types of loop available for use in tevent library:
+
+<ul>
+<li>int tevent_loop_wait()</li>
+<li>int tevent_loop_once()</li>
+</ul>
+
+Both of functions accept just one parametr (tevent context) and the only
+difference lies in the fact that the first loop can theoretically last for ever
+but the second one will wait just for a single one event to catch and then the
+loop breaks and the program continue.
+
+*/
diff --git a/lib/tevent/doc/tevent_data.dox b/lib/tevent/doc/tevent_data.dox
new file mode 100644
index 0000000..4ee4ac2
--- /dev/null
+++ b/lib/tevent/doc/tevent_data.dox
@@ -0,0 +1,133 @@
+/**
+ at page tevent_data Chapter 3: Accessing data
+ at section data Accessing data with tevent
+
+A tevent request is (usually) created together with a structure for storing the
+data necessary for an asynchronous computation. For these private data, tevent
+library uses void (generic) pointers, therefore any data type can be very
+simply pointed at. However, this attitude requires clear and guaranteed
+knowledge of the data type that will be handled, in advance. Private data can
+be of 2 types: connected with a request itself or given as an individual
+argument to a callback. It is necessary to differentiate these types, because
+there is a slightly different method of data access for each. There are two
+possibilities how to access data that is given as an argument directly to a
+callback. The difference lies in the pointer that is returned. In one case it
+is the data type specified in the function’s argument, in another void* is
+returned.
+
+ at code
+void tevent_req_callback_data (struct tevent_req *req, #type)
+void tevent_req_callback_data_void (struct tevent_req *req)
+ at endcode
+
+
+To obtain data that are strictly bound to a request, this function is the only
+direct procedure.
+
+ at code
+void *tevent_req_data (struct tevent_req *req, #type)
+ at endcode
+
+Example with both calls which differs between private data within tevent
+request and data handed over as an argument.
+
+ at code
+#include <stdio.h>
+#include <unistd.h>
+#include <tevent.h>
+
+struct foo_state {
+    int x;
+};
+
+struct testA {
+    int y;
+};
+
+
+static void foo_done(struct tevent_req *req) {
+// a->x contains 9
+struct foo_state *a = tevent_req_data(req, struct foo_state);
+
+// b->y contains 10
+struct testA *b = tevent_req_callback_data(req, struct testA);
+
+// c->y contains 10
+struct testA *c = (struct testA *)tevent_req_callback_data_void(req);
+
+printf("a->x: %d\n", a->x);
+printf("b->y: %d\n", b->y);
+printf("c->y: %d\n", c->y);
+}
+
+
+struct tevent_req * foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx) {
+
+printf("_send\n");
+struct tevent_req *req;
+struct foo_state *state;
+
+req = tevent_req_create(event_ctx, &state, struct foo_state);
+state->x = 10;
+
+return req;
+}
+
+static void run(struct tevent_context *ev, struct tevent_timer *te,
+                struct timeval current_time, void *private_data) {
+    struct tevent_req *req;
+    struct testA *tmp = talloc(ev, struct testA);
+    tmp->y = 9;
+    req = foo_send(ev, ev);
+
+    tevent_req_set_callback(req, foo_done, tmp);
+    tevent_req_done(req);
+
+}
+
+int main (int argc, char **argv) {
+
+    struct tevent_context *event_ctx;
+    struct testA *data;
+    TALLOC_CTX *mem_ctx;
+    struct tevent_timer *time_event;
+
+    mem_ctx = talloc_new(NULL); //parent
+    if (mem_ctx == NULL)
+        return EXIT_FAILURE;
+
+    event_ctx = tevent_context_init(mem_ctx);
+    if (event_ctx == NULL)
+        return EXIT_FAILURE;
+
+    data = talloc(mem_ctx, struct testA);
+    data->y = 10;
+
+    time_event = tevent_add_timer(event_ctx,
+                                  mem_ctx,
+                                  tevent_timeval_current(),
+                                  run,
+                                  data);
+    if (time_event == NULL) {
+        fprintf(stderr, " FAILED\n");
+        return EXIT_FAILURE;
+    }
+
+    tevent_loop_once(event_ctx);
+
+    talloc_free(mem_ctx);
+
+    printf("Quit\n");
+    return EXIT_SUCCESS;
+}
+ at endcode
+
+Output of this example is:
+
+ at code
+a->x: 9
+b->y: 10
+c->y: 10
+ at endcode
+
+*/
diff --git a/lib/tevent/doc/tevent_events.dox b/lib/tevent/doc/tevent_events.dox
new file mode 100644
index 0000000..8e350d2
--- /dev/null
+++ b/lib/tevent/doc/tevent_events.dox
@@ -0,0 +1,341 @@
+/**
+ at page tevent_events Chapter 2: Tevent events
+ at section pools Tevent events
+
+Ok, after reading previous chapter we can start doing something useful. So, the
+way of creating events is similar for all types - signals, file descriptors,
+time or immediate events. At the beginning it is good to know about some
+typedefs which are set in tevent library and which specify the arguments for
+each callback. These callbacks are:
+
+- tevent_timer_handler_t()
+
+- tevent_immediate_handler_t()
+
+- tevent_signal_handler_t()
+
+- tevent_fd_handler_t()
+
+According their names it is obvious that for creating callback for e.g. time
+event, tevent_timer_handler_t will be used.
+
+The best way how to introduce registering an event and setting up a callback
+would be example, so examples describing all the types of events follow.
+
+ at subsection Time Time event
+
+This example shows how to set up an event which will be repeated for a minute
+with interval of 2 seconds (will be triggered 30 times). After exceeding this
+limit, the event loop will finish and all the memory resources will be freed.
+This is just example describing repeated activity, nothing usefull is done
+within foo function
+
+ at code
+#include <stdio.h>
+#include <unistd.h>
+#include <tevent.h>
+#include <sys/time.h>
+
+struct state {
+     struct timeval endtime;
+     int counter;
+     TALLOC_CTX *ctx;
+};
+
+static void callback(struct tevent_context *ev, struct tevent_timer *tim,
+                     struct timeval current_time, void *private_data)
+{
+    struct state *data = talloc_get_type(private_data, struct state);
+    struct tevent_timer *time_event;
+    struct timeval schedule;
+
+    printf("Data value: %d\n", data->counter);
+    data->counter += 1; // increase counter
+
+    // if time has not reached its limit, set another event
+    if (tevent_timeval_compare(&current_time, &(data->endtime)) < 0) {
+        // do something
+        // set repeat with delay 2 seconds
+        schedule = tevent_timeval_current_ofs(2, 0);
+        time_event = tevent_add_timer(ev, data->ctx, schedule, callback, data);
+        if (time_event == NULL) { // error ...
+            fprintf(stderr, "MEMORY PROBLEM\n");
+            return;
+        }
+    } else {
+        // time limit exceeded
+    }
+}
+
+int main(void)  {
+    struct tevent_context *event_ctx;
+    TALLOC_CTX *mem_ctx;
+    struct tevent_timer *time_event;
+    struct timeval schedule;
+
+    mem_ctx = talloc_new(NULL); // parent
+    event_ctx = tevent_context_init(mem_ctx);
+
+    struct state *data = talloc(mem_ctx, struct state);
+
+    schedule = tevent_timeval_current_ofs(2, 0); // +2 second time value
+    data->endtime = tevent_timeval_add(&schedule, 60, 0); // one minute time limit
+    data->ctx = mem_ctx;
+    data->counter = 0;
+
+    // add time event
+    time_event = tevent_add_timer(event_ctx, mem_ctx, schedule, callback, data);
+    if (time_event == NULL) {
+        fprintf(stderr, "FAILED\n");
+        return EXIT_FAILURE;
+    }
+
+    tevent_loop_wait(event_ctx);
+    talloc_free(mem_ctx);
+    return EXIT_SUCCESS;
+}
+ at endcode
+
+Variable <code>counter</code> is only used for counting the number of triggered
+functions. List of all available functions which tevent offers for working with
+time are listed
+<a href="http://tevent.samba.org/group__tevent__helpers.html">here</a> together
+with their description. More detailed view at these functions is unnecessary
+because their purpose and usage is quite simple and clear.
+
+ at subsection Immediate Immediate event
+
+These events are, as their name indicates, activated and performed immediately.
+It means that this kind of events have priority over others (except signal
+events). So if there is a bulk of events registered and after that a
+tevent loop is launched, then all the immediate events will be triggered before
+the other events. Except other immediate events (and signal events) because
+they are also processed sequentially - according the order they were scheduled.
+Signals have the highest priority and therefore they are processed
+preferentially. Therefore the expression immediate may not correspond exactly
+to the dictionary definition of "something without delay" but rather "as soon
+as possible" after all preceding immediate events.
+
+For creating an immediate event there is a small different which lies in the
+fact that the creation of such event is done in 2 steps. One represents the
+creation (memory allocation), the second one represents registering as the
+event within some tevent context.
+
+ at code
+struct tevent_immediate *run(TALLOC_CTX* mem_ctx,
+                             struct tevent_context event_ctx,
+                             void * data)
+{
+    struct tevent_immediate *im;
+
+    im = tevent_create_immediate(mem_ctx);
+    if (im == NULL) {
+        return NULL;
+    }
+    tevent_schedule_immediate(im, event_ctx, foo, data);
+
+    return im;
+}
+ at endcode
+
+Example which may be compiled and run representing the creation of immediate event.
+
+ at code
+
+#include <stdio.h>
+#include <unistd.h>
+#include <tevent.h>
+
+struct info_struct {
+    int counter;
+};
+
+static void foo(struct tevent_context *ev, struct tevent_immediate *im,
+                void *private_data)
+{
+    struct info_struct *data = talloc_get_type(private_data, struct info_struct);
+    printf("Data value: %d\n", data->counter);
+}
+
+int main (void) {
+    struct tevent_context *event_ctx;
+    TALLOC_CTX *mem_ctx;
+    struct tevent_immediate *im;
+
+    printf("INIT\n");
+
+    mem_ctx = talloc_new(NULL);
+    event_ctx = tevent_context_init(mem_ctx);
+
+    struct info_struct *data = talloc(mem_ctx, struct info_struct);
+
+    // setting up private data
+    data->counter = 1;
+
+    // first immediate event
+    im = tevent_create_immediate(mem_ctx);
+    if (im == NULL) {
+        fprintf(stderr, "FAILED\n");
+        return EXIT_FAILURE;
+    }
+    tevent_schedule_immediate(im, event_ctx, foo, data);
+
+    tevent_loop_wait(event_ctx);
+    talloc_free(mem_ctx);
+
+    return 0;
+}
+ at endcode
+
+ at subsection Signal Signal event
+
+This is an alternative to standard C library functions signal() or sigaction().
+The main difference that distinguishes these ways of treating signals is their
+setting up of handlers for different time intervals of the running program. 
+
+While standard C library methods for dealing with signals offer sufficient
+tools for most cases, they are inadequate for handling signals within the
+tevent loop. It could be necessary to finish certain tevent requests within the
+tevent loop without interruption. If a signal was sent to a program at a moment
+when the tevent loop is in progress, a standard signal handler would not return
+processing to the application at the very same place and it would quit the
+tevent loop for ever. In such cases, tevent signal handlers offer the
+possibility of dealing with these signals by masking them from the rest of
+application and not quitting the loop, so the other events can still be
+processed.
+
+Tevent offers also a control function, which enables us to verify whether it is
+possible to handle signals via tevent, is defined within tevent library and it
+returns a boolean value revealing the result of the verification.
+
+ at code
+bool tevent_signal_support (struct tevent_context *ev)
+ at endcode
+
+Checking for signal support is not necessary, but if it is not guaranteed, this
+is a good and easy control to prevent unexpected behaviour or failure of the
+program occurring. Such a test of course does not have to be run every single
+time you wish to create a signal handler, but simply at the beginning - during
+the initialization procedures of the program. Afterthat, simply adapt to each
+situation that arises.
+
+ at code
+
+#include <stdio.h>
+#include <tevent.h>
+#include <signal.h>
+
+static void handler(struct tevent_context *ev,
+                    struct tevent_signal *se,
+                    int signum,
+                    int count,
+                    void *siginfo,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list