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