]> rtime.felk.cvut.cz Git - frescor/frsh.git/commitdiff
Fixed race condition in allocator registration
authorMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 10 Nov 2009 13:35:51 +0000 (14:35 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 10 Nov 2009 13:35:51 +0000 (14:35 +0100)
This happened when multiple threads tried to negotiate contracts
simultaneously. The first negotiation triggers registration
of FRA with FCB and the check whether the FRA is already registered
was not protected by any mutex.

fres/resalloc/fra_generic.h
fres/resalloc/fra_registry.c
frsh_api/frsh_core.c

index 512a6c24e9b5b347d81d8b2ef24a1c04a1c1d62b..650e3df6630bef6715dcd1def280b235a3e700d6 100644 (file)
@@ -209,9 +209,9 @@ fres_resource_allocator fra_new(forb_orb orb,
                                forb_executor_t *executor,
                                struct fres_allocator *allocator);
 
-void fra_registry_init(forb_orb                   orb,
-                      fres_contract_broker fcb,
-                      forb_executor_t     *executor);
+int fra_registry_init(forb_orb            orb,
+                     fres_contract_broker fcb,
+                     forb_executor_t      *executor);
 int fra_register(struct fres_allocator *allocator);
 int fra_activate(frsh_resource_type_t res_type,
                 frsh_resource_id_t   res_id);
index 464a26feb114d512f85fc9285efc018291bbb99e..44bdf0e2f88401bbde2559f1169901fe8a9a5bdc 100644 (file)
@@ -90,6 +90,7 @@ static struct registry {
        fres_contract_broker    fcb;
        forb_executor_t         *executor;
 
+       pthread_mutex_t         mutex;
        gavl_cust_root_field_t  allocators;
 } registry;
 
@@ -135,16 +136,25 @@ GAVL_CUST_NODE_INT_IMP(fra_registry       /* cust_prefix */,
  * @param orb
  * @param fcb Contract broker object reference
  * @param executor Executor for all allocator objects
+ *
+ * @return Zero on success, error number on error.
  */
-void fra_registry_init(forb_orb                   orb,
+int fra_registry_init(forb_orb            orb,
                       fres_contract_broker fcb,
                       forb_executor_t     *executor)
 {
+       int rv;
        registry.orb = orb;
        registry.fcb = fcb;
        registry.executor = executor;
 
+       pthread_mutexattr_t ma;
+       rv = pthread_mutexattr_init(&ma);
+       rv = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT);
+       if (rv) return rv;
+       pthread_mutex_init(&registry.mutex, &ma);
        fra_registry_init_root_field(&registry);
+       return 0;
 }
 
 /** 
@@ -158,7 +168,7 @@ int fra_register(struct fres_allocator *allocator)
 {
        struct registered_allocator *ra;
        int ret;
-       
+       pthread_mutex_lock(&registry.mutex);
        ra = fra_registry_find(&registry, &allocator);
        if (!ra && free_allocator_idx < FRA_MAX_ALLOCATORS) {
                ra = &allocators[free_allocator_idx];
@@ -170,6 +180,7 @@ int fra_register(struct fres_allocator *allocator)
        } else {
                ret = -1;
        }
+       pthread_mutex_unlock(&registry.mutex);
        return ret;
 }
 
@@ -231,6 +242,7 @@ int fra_activate(frsh_resource_type_t res_type,
        
        key.res_type = res_type;
        key.res_id = res_id;
+       pthread_mutex_lock(&registry.mutex);
        ra = fra_registry_find(&registry, &pkey);
        if (ra) {
                if (ra->registered_with_fcb) {
@@ -244,6 +256,7 @@ int fra_activate(frsh_resource_type_t res_type,
        } else {
                ret = FRES_ERR_NO_RESOURCE_ALLOCATOR;
        }
+       pthread_mutex_unlock(&registry.mutex);
 
        return ret;
 }
@@ -266,8 +279,10 @@ struct fres_allocator *fra_get(frsh_resource_type_t res_type,
 
        pkey->res_type = res_type;
        pkey->res_id = res_id;
-       
+
+       pthread_mutex_lock(&registry.mutex);
        ra = fra_registry_find(&registry, &pkey);
+       pthread_mutex_unlock(&registry.mutex);
        if (ra) {
                return ra->allocator;
        } else {
index 084e691620b88931b5927e93e210e080504a8f7f..111bd76fe3d5592ca5a9011d96464abaf03a452d 100644 (file)
@@ -118,8 +118,9 @@ int frsh_init()
        ret = forb_executor_init(&frsh_forb_global.alloc_executor);
        if (ret) goto err;
 
-       fra_registry_init(frsh_forb_global.orb, frsh_forb_global.fcb,
-                         &frsh_forb_global.alloc_executor);
+       ret = fra_registry_init(frsh_forb_global.orb, frsh_forb_global.fcb,
+                               &frsh_forb_global.alloc_executor);
+       if (ret) goto err;
        
 #ifdef CONFIG_AQUOSA
        ret = aqcpu_fra_init();