update getpnn to use a generic "set_callback" call to register the callback on the...
[sahlberg/ctdb.git] / include / ctdb.h
index d44fca229d2da0dc6a8df865af9d84230b8c3ead..980e85574911c758393040360218cb1917db5de0 100644 (file)
 /* Functions are not thread safe so all function calls must be wrapped
  * inside a pthread_mutex for threaded applications.
  *
- * All _send() functions are guaranteed to be non-blocking and fully
+ * All *_send() functions are guaranteed to be non-blocking and fully
  * asynchronous.
  *
- * Avoid using the synchronous calls
+ * The return data from a _send() call can be accessed through two different
+ * mechanisms.
+ *
+ * 1, by calling *_recv() directly on the handle.
+ *    This function will block until the response is received so it
+ *    should be avoided.
+ *    The exception is when called from in the registered callback,
+ *    in this case the fucntion is guaranteed not to block.
+ *
+ * 2, Registering an async callback to be invoked when the call completes.
+ *    From inside the callback you use the *_recv() function to extract the
+ *    response data.
+ *
+ * After the *_recv() function returns, the handle will have been destroyed.
  */
 
 /*
@@ -64,15 +77,42 @@ int ctdb_service(struct ctdb_context *ctdb);
 typedef void ctdb_handle;
 
 
+/*
+ * After issuing a *_send() command, you can use this function to register a
+ * a callback function to be automatically called once the call
+ * finishes.
+ *
+ * Once the callback function returns, the handle will be automatically
+ * destroyed.
+ *
+ * If using ctdb_free() to abort a call in flight, you have to take care
+ * to avoid the race condition that would exist between the callback and
+ * ctdb_free().
+ *
+ * Possible method could be :
+ * * take pthreads mutex
+ * * ctdb_set_callback(handle, NULL, NULL)
+ * * verify that the callback has not yet been called
+ *     (if it has handle is no longer valid)
+ * * ctdb_free(handle)
+ * * release pthreads mutex
+ */
+typedef void (*ctdb_callback)(int32_t status, struct ctdb_context *ctdb, ctdb_handle *, void *private_data);
+
+int ctdb_set_callback(ctdb_handle *handle, ctdb_callback callback, void *private_data);
+
+
+
+
 /*
  * functions to attach to a database
  * if the database does not exist it will be created.
  *
- * Use ctdb_free() to release the returned ctdb_db_context when finished.
+ * You have to free the handle with ctdb_free() when finished with it.
  */
 struct ctdb_db_context;
 
-typedef void (*ctdb_attachdb_cb)(int32_t status, struct ctdb_db_context *ctdb_db, void *private_data);
+typedef void (*ctdb_attachdb_cb)(int32_t status, ctdb_handle *, struct ctdb_db_context *ctdb_db, void *private_data);
 
 ctdb_handle *
 ctdb_attachdb_send(struct ctdb_context *ctdb,
@@ -86,6 +126,47 @@ int ctdb_attachdb(struct ctdb_context *ctdb,
                  struct ctdb_db_context **);
 
 
+/*
+ * functions to read a record from the database
+ * when the callback is invoked, the client will hold an exclusive lock
+ * on the record, until the handle is ctdb_free()d.
+ * the client MUST NOT block during holding this lock and MUST
+ * release it quickly by performing ctdb_free(handle).
+ *
+ * When the handle is freed, data is freed too, so make sure to copy the data
+ * before freeing the handle.
+ */
+typedef void (*ctdb_readrecordlock_cb)(int32_t status, ctdb_handle *handle, TDB_DATA data, void *private_data);
+
+ctdb_handle *
+ctdb_readrecordlock_send(struct ctdb_context *ctdb,
+               struct ctdb_db_context *ctdb_db_context,
+               TDB_DATA key,
+               ctdb_readrecordlock_cb callback,
+               void *private_data);
+int ctdb_readrecordlock_recv(struct ctdb_context *ctdb,
+               ctdb_handle *handle,
+               TDB_DATA **data);
+int ctdb_readrecordlock(struct ctdb_context *ctdb,
+               struct ctdb_db_context *ctdb_db_context,
+               TDB_DATA key,
+               TDB_DATA **data);
+
+
+
+/*
+ * Function to write data to a record
+ * This function may ONLY be called while holding a lock to the record 
+ * created by ctdb_readrecordlock*
+ * Either from the callback provided to ctdb_readrecordlock_send()
+ * or after calling ctdb_readrecordlock_recv() but before calling
+ * ctdb_free() to release the handle.
+ */
+int ctdb_writerecord(ctdb_handle *handle,
+               TDB_DATA key,
+               TDB_DATA data);
+
+
 
 /*
  * messaging functions
@@ -141,13 +222,9 @@ int ctdb_send_message(struct ctdb_context *ctdb, uint32_t pnn, uint64_t srvid, T
 /*
  * functions to read the pnn number of the local node
  */
-typedef void (*ctdb_getpnn_cb)(int32_t status, int32_t pnn, void *private_data);
-
 ctdb_handle *
 ctdb_getpnn_send(struct ctdb_context *ctdb,
-                uint32_t destnode,
-                ctdb_getpnn_cb callback,
-                void *private_data);
+                uint32_t destnode);
 int ctdb_getpnn_recv(struct ctdb_context *ctdb,
                     ctdb_handle *handle,
                     uint32_t *pnn);