diff options
Diffstat (limited to 'src/ipcpd')
| -rw-r--r-- | src/ipcpd/shim-data.c | 113 | ||||
| -rw-r--r-- | src/ipcpd/shim-data.h | 9 | ||||
| -rw-r--r-- | src/ipcpd/shim-eth-llc/main.c | 26 | 
3 files changed, 87 insertions, 61 deletions
| diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c index 747a210b..355cec68 100644 --- a/src/ipcpd/shim-data.c +++ b/src/ipcpd/shim-data.c @@ -46,6 +46,40 @@ struct dir_entry {          uint64_t         addr;  }; +static void destroy_dir_query(struct dir_query * query) +{ +        assert(query); + +        pthread_mutex_lock(&query->lock); + +        switch (query->state) { +        case QUERY_INIT: +                query->state = QUERY_DONE; +                break; +        case QUERY_PENDING: +                query->state = QUERY_DESTROY; +                pthread_cond_broadcast(&query->cond); +                break; +        case QUERY_RESPONSE: +        case QUERY_DONE: +                break; +        case QUERY_DESTROY: +                pthread_mutex_unlock(&query->lock); +                return; +        } + +        while (query->state != QUERY_DONE) +                pthread_cond_wait(&query->cond, &query->lock); + +        pthread_mutex_unlock(&query->lock); + +        pthread_cond_destroy(&query->cond); +        pthread_mutex_destroy(&query->lock); + +        free(query->hash); +        free(query); +} +  static struct reg_entry * reg_entry_create(uint8_t * hash)  {          struct reg_entry * entry = malloc(sizeof(*entry)); @@ -151,7 +185,7 @@ static void clear_dir_queries(struct shim_data * data)          list_for_each_safe(h, t, &data->dir_queries) {                  struct dir_query * e = list_entry(h, struct dir_query, next);                  list_del(&e->next); -                shim_data_dir_query_destroy(e); +                destroy_dir_query(e);          }  } @@ -391,7 +425,8 @@ uint64_t shim_data_dir_get_addr(struct shim_data * data,          return addr;  } -struct dir_query * shim_data_dir_query_create(const uint8_t * hash) +struct dir_query * shim_data_dir_query_create(struct shim_data * data, +                                              const uint8_t *    hash)  {          struct dir_query * query;          pthread_condattr_t cattr; @@ -417,58 +452,64 @@ struct dir_query * shim_data_dir_query_create(const uint8_t * hash)          list_head_init(&query->next); +        pthread_mutex_lock(&data->dir_queries_lock); +        list_add(&query->next, &data->dir_queries); +        pthread_mutex_unlock(&data->dir_queries_lock); +          return query;  } -void shim_data_dir_query_respond(struct dir_query * query) +void shim_data_dir_query_respond(struct shim_data * data, +                                 const uint8_t *    hash)  { -        assert(query); +        struct dir_query * e = NULL; +        struct list_head * pos; +        bool               found = false; -        pthread_mutex_lock(&query->lock); - -        if (query->state != QUERY_PENDING) { -                pthread_mutex_unlock(&query->lock); -                return; -        } - -        query->state = QUERY_RESPONSE; -        pthread_cond_broadcast(&query->cond); +        pthread_mutex_lock(&data->dir_queries_lock); -        while (query->state == QUERY_RESPONSE) -                pthread_cond_wait(&query->cond, &query->lock); +        list_for_each(pos, &data->dir_queries) { +                e = list_entry(pos, struct dir_query, next); -        pthread_mutex_unlock(&query->lock); -} +                if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0) { +                        found = true; +                        break; +                } +        } -void shim_data_dir_query_destroy(struct dir_query * query) -{ -        assert(query); +        if (!found) { +                pthread_mutex_unlock(&data->dir_queries_lock); +                return; +        } -        pthread_mutex_lock(&query->lock); +        pthread_mutex_lock(&e->lock); -        if (query->state == QUERY_DESTROY) { -                pthread_mutex_unlock(&query->lock); +        if (e->state != QUERY_PENDING) { +                pthread_mutex_unlock(&e->lock); +                pthread_mutex_unlock(&data->dir_queries_lock);                  return;          } -        if (query->state == QUERY_INIT) -                query->state = QUERY_DONE; +        e->state = QUERY_RESPONSE; +        pthread_cond_broadcast(&e->cond); -        if (query->state == QUERY_PENDING) { -                query->state = QUERY_DESTROY; -                pthread_cond_broadcast(&query->cond); -        } +        while (e->state == QUERY_RESPONSE) +                pthread_cond_wait(&e->cond, &e->lock); -        while (query->state != QUERY_DONE) -                pthread_cond_wait(&query->cond, &query->lock); +        pthread_mutex_unlock(&e->lock); -        pthread_mutex_unlock(&query->lock); +        pthread_mutex_unlock(&data->dir_queries_lock); +} -        pthread_cond_destroy(&query->cond); -        pthread_mutex_destroy(&query->lock); +void shim_data_dir_query_destroy(struct shim_data * data, +                                 struct dir_query * query) +{ +        pthread_mutex_lock(&data->dir_queries_lock); -        free(query->hash); -        free(query); +        list_del(&query->next); +        destroy_dir_query(query); + +        pthread_mutex_unlock(&data->dir_queries_lock);  }  int shim_data_dir_query_wait(struct dir_query *      query, diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h index 983f97f6..6380eea7 100644 --- a/src/ipcpd/shim-data.h +++ b/src/ipcpd/shim-data.h @@ -85,11 +85,14 @@ bool               shim_data_dir_has(struct shim_data * data,  uint64_t           shim_data_dir_get_addr(struct shim_data * data,                                            const uint8_t *    hash); -struct dir_query * shim_data_dir_query_create(const uint8_t * hash); +struct dir_query * shim_data_dir_query_create(struct shim_data * data, +                                              const uint8_t *    hash); -void               shim_data_dir_query_respond(struct dir_query * query); +void               shim_data_dir_query_destroy(struct shim_data * data, +                                               struct dir_query * query); -void               shim_data_dir_query_destroy(struct dir_query * query); +void               shim_data_dir_query_respond(struct shim_data * data, +                                               const uint8_t *    hash);  int                shim_data_dir_query_wait(struct dir_query *      query,                                              const struct timespec * timeout); diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index e5f0cba8..b8e987ba 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -512,24 +512,13 @@ static int eth_llc_ipcp_name_query_req(const uint8_t * hash,  static int eth_llc_ipcp_name_query_reply(const uint8_t * hash,                                           uint8_t *       r_addr)  { -        uint64_t           address = 0; -        struct list_head * pos; +        uint64_t address = 0;          memcpy(&address, r_addr, MAC_SIZE);          shim_data_dir_add_entry(eth_llc_data.shim_data, hash, address); -        pthread_mutex_lock(ð_llc_data.shim_data->dir_queries_lock); - -        list_for_each(pos, ð_llc_data.shim_data->dir_queries) { -                struct dir_query * e = -                        list_entry(pos, struct dir_query, next); -                if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0) { -                        shim_data_dir_query_respond(e); -                } -        } - -        pthread_mutex_unlock(ð_llc_data.shim_data->dir_queries_lock); +        shim_data_dir_query_respond(eth_llc_data.shim_data, hash);          return 0;  } @@ -1053,22 +1042,15 @@ static int eth_llc_ipcp_query(const uint8_t * hash)          memset(r_addr, 0xff, MAC_SIZE); -        query = shim_data_dir_query_create(hash); +        query = shim_data_dir_query_create(eth_llc_data.shim_data, hash);          if (query == NULL)                  return -1; -        pthread_mutex_lock(ð_llc_data.shim_data->dir_queries_lock); -        list_add(&query->next, ð_llc_data.shim_data->dir_queries); -        pthread_mutex_unlock(ð_llc_data.shim_data->dir_queries_lock); -          eth_llc_ipcp_send_mgmt_frame(&msg, r_addr);          ret = shim_data_dir_query_wait(query, &timeout); -        pthread_mutex_lock(ð_llc_data.shim_data->dir_queries_lock); -        list_del(&query->next); -        shim_data_dir_query_destroy(query); -        pthread_mutex_unlock(ð_llc_data.shim_data->dir_queries_lock); +        shim_data_dir_query_destroy(eth_llc_data.shim_data, query);          return ret;  } | 
