]> git.meshlink.io Git - catta/blobdiff - avahi-compat-howl/compat.c
add new client state AVAHI_CLIENT_FAILURE
[catta] / avahi-compat-howl / compat.c
index 0f464638d08c9e483396892cff47bd97bfec2458..8db8fe0233b33edad01ae0539390871c68015821 100644 (file)
 #include <avahi-common/simple-watch.h>
 #include <avahi-common/error.h>
 #include <avahi-common/llist.h>
+
 #include <avahi-client/client.h>
+#include <avahi-client/publish.h>
+#include <avahi-client/lookup.h>
 
 #include "howl.h"
 #include "warn.h"
@@ -43,7 +46,8 @@
 enum {
     COMMAND_POLL = 'p',
     COMMAND_QUIT = 'q',
-    COMMAND_POLL_DONE = 'P'
+    COMMAND_POLL_DONE = 'P',
+    COMMAND_POLL_FAILED = 'F'
 };
 
 typedef enum {
@@ -87,7 +91,7 @@ struct _sw_discovery {
     pthread_t thread;
     int thread_running;
 
-    pthread_mutex_t mutex;
+    pthread_mutex_t mutex, salt_mutex;
 
     AVAHI_LLIST_HEAD(service_data, services);
 };
@@ -183,22 +187,32 @@ static void * thread_func(void *data) {
         
         switch (command) {
 
-            case COMMAND_POLL:
+            case COMMAND_POLL: {
+                int ret;
 
                 ASSERT_SUCCESS(pthread_mutex_lock(&self->mutex));
+
+                for (;;) {
+                    errno = 0;
                 
-                if (avahi_simple_poll_run(self->simple_poll) < 0) {
-                    fprintf(stderr, __FILE__": avahi_simple_poll_run() failed.\n");
-                    ASSERT_SUCCESS(pthread_mutex_unlock(&self->mutex));
+                    if ((ret = avahi_simple_poll_run(self->simple_poll)) < 0) {
+                        
+                        if (errno == EINTR)
+                            continue;
+                        
+                        fprintf(stderr, __FILE__": avahi_simple_poll_run() failed: %s\n", strerror(errno));
+                    }
+
                     break;
                 }
-
+                    
                 ASSERT_SUCCESS(pthread_mutex_unlock(&self->mutex));
                 
-                if (write_command(self->thread_fd, COMMAND_POLL_DONE) < 0)
+                if (write_command(self->thread_fd, ret < 0 ? COMMAND_POLL_FAILED : COMMAND_POLL_DONE) < 0)
                     break;
                 
                 break;
+            }
 
             case COMMAND_QUIT:
                 return NULL;
@@ -359,6 +373,7 @@ sw_result sw_discovery_init(sw_discovery * self) {
     ASSERT_SUCCESS(pthread_mutexattr_init(&mutex_attr));
     pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
     ASSERT_SUCCESS(pthread_mutex_init(&(*self)->mutex, &mutex_attr));
+    ASSERT_SUCCESS(pthread_mutex_init(&(*self)->salt_mutex, &mutex_attr));
 
     if (!((*self)->simple_poll = avahi_simple_poll_new()))
         goto fail;
@@ -440,6 +455,7 @@ static void discovery_unref(sw_discovery self) {
         close(self->main_fd);
 
     ASSERT_SUCCESS(pthread_mutex_destroy(&self->mutex));
+    ASSERT_SUCCESS(pthread_mutex_destroy(&self->salt_mutex));
 
     while (self->services)
         service_data_free(self, self->services);
@@ -574,8 +590,10 @@ sw_result sw_salt_step(sw_salt self, sw_uint32 * msec) {
 
 sw_result sw_salt_run(sw_salt self) {
     sw_result ret;
-    
+
     AVAHI_WARN_LINKAGE;
+
+    assert(self);
     
     for (;;)
         if ((ret = sw_salt_step(self, NULL)) != SW_OKAY)
@@ -585,12 +603,33 @@ sw_result sw_salt_run(sw_salt self) {
 sw_result sw_salt_stop_run(sw_salt self) {
     AVAHI_WARN_LINKAGE;
 
+    assert(self);
+
     if (stop_thread((sw_discovery) self) < 0)
         return SW_E_UNKNOWN;
 
     return SW_OKAY;
 }
 
+sw_result sw_salt_lock(sw_salt self) {
+    AVAHI_WARN_LINKAGE;
+
+    assert(self);
+    ASSERT_SUCCESS(pthread_mutex_lock(&((sw_discovery) self)->salt_mutex));
+
+    return SW_OKAY;
+}
+
+sw_result sw_salt_unlock(sw_salt self) {
+    assert(self);
+    
+    AVAHI_WARN_LINKAGE;
+
+    ASSERT_SUCCESS(pthread_mutex_unlock(&((sw_discovery) self)->salt_mutex));
+
+    return SW_OKAY;
+}
+
 static void reg_report_status(oid_data *data, sw_discovery_publish_status status) {
     sw_discovery_publish_reply reply;
 
@@ -655,6 +694,7 @@ static void reg_client_callback(oid_data *data, AvahiClientState state) {
         return;
     
     switch (state) {
+        case AVAHI_CLIENT_FAILURE:
         case AVAHI_CLIENT_DISCONNECTED:
             reg_report_status(data, SW_DISCOVERY_PUBLISH_INVALID);
             break;
@@ -677,7 +717,6 @@ static void reg_client_callback(oid_data *data, AvahiClientState state) {
             avahi_entry_group_reset(data->object);
             break;
 
-        case AVAHI_CLIENT_S_INVALID:
         case AVAHI_CLIENT_S_REGISTERING:
             /* Ignore */
             break;
@@ -706,6 +745,11 @@ static void reg_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState st
         case AVAHI_ENTRY_GROUP_UNCOMMITED:
             /* Ignore */
             break;
+
+        case AVAHI_ENTRY_GROUP_FAILURE:
+            reg_report_status(data, SW_DISCOVERY_PUBLISH_INVALID);
+            break;
+            
     }
 }
 
@@ -726,6 +770,7 @@ sw_result sw_discovery_publish(
     oid_data *data;
     sw_result result = SW_E_UNKNOWN;
     service_data *sdata;
+    AvahiStringList *txt = NULL;
     
     assert(self);
     assert(name);
@@ -735,10 +780,17 @@ sw_result sw_discovery_publish(
     
     AVAHI_WARN_LINKAGE;
 
-    if ((*oid = oid_alloc(self, OID_ENTRY_GROUP)) == (sw_discovery_oid) -1)
+    if (text_record && text_record_len > 0)
+        if (avahi_string_list_parse(text_record, text_record_len, &txt) < 0)
+            return SW_E_UNKNOWN;
+
+    if ((*oid = oid_alloc(self, OID_ENTRY_GROUP)) == (sw_discovery_oid) -1) {
+        avahi_string_list_free(txt);
         return SW_E_UNKNOWN;
+    }
 
     if (!(sdata = service_data_new(self))) {
+        avahi_string_list_free(txt);
         oid_release(self, *oid);
         return SW_E_MEM;
     }
@@ -755,7 +807,7 @@ sw_result sw_discovery_publish(
     sdata->domain = domain ? avahi_normalize_name_strdup(domain) : NULL;
     sdata->host = host ? avahi_normalize_name_strdup(host) : NULL;
     sdata->port = port;
-    sdata->txt = text_record && text_record_len > 0 ? avahi_string_list_parse(text_record, text_record_len) : NULL;
+    sdata->txt = txt;
 
     /* Some OOM checking would be cool here */
 
@@ -791,10 +843,10 @@ finish:
 static void domain_browser_callback(
     AvahiDomainBrowser *b,
     AvahiIfIndex interface,
-    AvahiProtocol protocol,
+    AVAHI_GCC_UNUSED AvahiProtocol protocol,
     AvahiBrowserEvent event,
     const char *domain,
-    AvahiLookupResultFlags flags,
+    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
     void *userdata) {
 
     oid_data* data = userdata;
@@ -877,7 +929,7 @@ finish:
 static void service_resolver_callback(
     AvahiServiceResolver *r,
     AvahiIfIndex interface,
-    AvahiProtocol protocol,
+    AVAHI_GCC_UNUSED AvahiProtocol protocol,
     AvahiResolverEvent event,
     const char *name,
     const char *type,
@@ -886,7 +938,7 @@ static void service_resolver_callback(
     const AvahiAddress *a,
     uint16_t port,
     AvahiStringList *txt,
-    AvahiLookupResultFlags flags,
+    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
     void *userdata) {
 
     oid_data* data = userdata;
@@ -986,12 +1038,12 @@ finish:
 static void service_browser_callback(
     AvahiServiceBrowser *b,
     AvahiIfIndex interface,
-    AvahiProtocol protocol,
+    AVAHI_GCC_UNUSED AvahiProtocol protocol,
     AvahiBrowserEvent event,
     const char *name,
     const char *type,
     const char *domain,
-    AvahiLookupResultFlags flags,
+    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
     void *userdata) {
 
     oid_data* data = userdata;