PloverPackageSet shouldn't try and acquire the same razor lock twice
authorJ. Ali Harlow <ali@juiblex.co.uk>
Thu Jun 07 15:56:09 2018 +0100 (2018-06-07)
changeset 732ba231a7973e
parent 72 9f4b672bd85c
child 74 a69a7f215b92
PloverPackageSet shouldn't try and acquire the same razor lock twice
plover/packageset.c
     1.1 --- a/plover/packageset.c	Tue Jun 05 17:21:56 2018 +0100
     1.2 +++ b/plover/packageset.c	Thu Jun 07 15:56:09 2018 +0100
     1.3 @@ -62,25 +62,15 @@
     1.4  
     1.5  static void plover_package_set_dispose(GObject *obj)
     1.6  {
     1.7 -    PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
     1.8 +    PloverPackageSet *set=PLOVER_PACKAGE_SET(obj);
     1.9 +    PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
    1.10      if (priv->packages)
    1.11      {
    1.12  	g_slist_foreach(priv->packages,(GFunc)g_object_unref,NULL);
    1.13  	g_slist_free(priv->packages);
    1.14  	priv->packages=NULL;
    1.15      }
    1.16 -    if (priv->set)
    1.17 -    {
    1.18 -	razor_set_unref(priv->set);
    1.19 -	priv->set=NULL;
    1.20 -    }
    1.21 -    if (priv->root)
    1.22 -    {
    1.23 -	g_free(priv->root_uri);
    1.24 -	priv->root_uri=NULL;
    1.25 -	razor_root_close(priv->root);
    1.26 -	priv->root=NULL;
    1.27 -    }
    1.28 +    plover_package_set_close(set);
    1.29      G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj);
    1.30  }
    1.31  
    1.32 @@ -113,22 +103,51 @@
    1.33      PloverPackageSetPrivate *priv;
    1.34      g_return_if_fail(PLOVER_IS_PACKAGE_SET(set));
    1.35      priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
    1.36 +    if (priv->set)
    1.37 +    {
    1.38 +	razor_set_unref(priv->set);
    1.39 +	priv->set=NULL;
    1.40 +    }
    1.41      if (priv->root)
    1.42      {
    1.43  	razor_root_close(priv->root);
    1.44  	priv->root=NULL;
    1.45      }
    1.46 +    if (priv->root_uri)
    1.47 +    {
    1.48 +	g_free(priv->root_uri);
    1.49 +	priv->root_uri=NULL;
    1.50 +    }
    1.51  }
    1.52  
    1.53  gboolean plover_package_set_open(PloverPackageSet *set,const char *root_uri,
    1.54    gboolean exclusive,GError **err)
    1.55  {
    1.56 +    gboolean incompatible_lock=FALSE;
    1.57      struct razor_root *root=NULL;
    1.58      struct razor_set *system=NULL;
    1.59      PloverPackageSetPrivate *priv;
    1.60      struct razor_error *error=NULL;
    1.61      g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
    1.62      g_return_val_if_fail(plover__uri_validate(root_uri),FALSE);
    1.63 +    priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
    1.64 +    /*
    1.65 +     * If we're opening a different root_uri, then we can simply open the
    1.66 +     * new root first and then close the old root if we're successful.
    1.67 +     * Otherwise, if we're changing the lock type we have to close the
    1.68 +     * old lock first which allows for the possibility of failing to
    1.69 +     * re-open the old root on failure. That's unfortunate but appears
    1.70 +     * unavoidable; MS-Windows doesn't appear to have the ability to
    1.71 +     * either upgrade or downgrade a file lock.
    1.72 +     */
    1.73 +    if (!g_strcmp0(root_uri,priv->root_uri))
    1.74 +    {
    1.75 +	incompatible_lock=!priv->root!=!exclusive;
    1.76 +	if (incompatible_lock)
    1.77 +	    plover_package_set_close(set);
    1.78 +	else
    1.79 +	    return TRUE;
    1.80 +    }
    1.81      if (exclusive)
    1.82      {
    1.83  	root=razor_root_open(root_uri,NULL);
    1.84 @@ -150,6 +169,8 @@
    1.85  	    if (!root)                        
    1.86  	    {
    1.87  		plover_propagate_razor_error(err,error);
    1.88 +		if (incompatible_lock)
    1.89 +		    (void)plover_package_set_open(set,root_uri,!exclusive,NULL);
    1.90  		return FALSE;
    1.91  	    }
    1.92  	}
    1.93 @@ -164,23 +185,14 @@
    1.94  	g_set_error_literal(err,PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED,
    1.95  	  razor_error_get_msg(error));
    1.96  	razor_error_free(error);
    1.97 +	if (incompatible_lock)
    1.98 +	    (void)plover_package_set_open(set,root_uri,!exclusive,NULL);
    1.99  	return FALSE;
   1.100      }
   1.101 -    priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
   1.102 -    if (priv->set)
   1.103 -    {
   1.104 -	razor_set_unref(priv->set);
   1.105 -	priv->set=NULL;
   1.106 -    }
   1.107 -    if (priv->root)
   1.108 -    {
   1.109 -	razor_root_close(priv->root);
   1.110 -	priv->root=NULL;
   1.111 -    }
   1.112 -    g_free(priv->root_uri);
   1.113 -    priv->root_uri=g_strdup(root_uri);
   1.114 +    plover_package_set_close(set);
   1.115      priv->root=root;
   1.116      priv->set=system;
   1.117 +    priv->root_uri=g_strdup(root_uri);
   1.118      return TRUE;
   1.119  }
   1.120