# HG changeset patch # User J. Ali Harlow # Date 1528383369 -3600 # Node ID 2ba231a7973ef32c56207b0e1d288b4c70304735 # Parent 9f4b672bd85c66feb629086bedc98fdceb419870 PloverPackageSet shouldn't try and acquire the same razor lock twice diff -r 9f4b672bd85c -r 2ba231a7973e plover/packageset.c --- a/plover/packageset.c Tue Jun 05 17:21:56 2018 +0100 +++ b/plover/packageset.c Thu Jun 07 15:56:09 2018 +0100 @@ -62,25 +62,15 @@ static void plover_package_set_dispose(GObject *obj) { - PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); + PloverPackageSet *set=PLOVER_PACKAGE_SET(obj); + PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); if (priv->packages) { g_slist_foreach(priv->packages,(GFunc)g_object_unref,NULL); g_slist_free(priv->packages); priv->packages=NULL; } - if (priv->set) - { - razor_set_unref(priv->set); - priv->set=NULL; - } - if (priv->root) - { - g_free(priv->root_uri); - priv->root_uri=NULL; - razor_root_close(priv->root); - priv->root=NULL; - } + plover_package_set_close(set); G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj); } @@ -113,22 +103,51 @@ PloverPackageSetPrivate *priv; g_return_if_fail(PLOVER_IS_PACKAGE_SET(set)); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); + if (priv->set) + { + razor_set_unref(priv->set); + priv->set=NULL; + } if (priv->root) { razor_root_close(priv->root); priv->root=NULL; } + if (priv->root_uri) + { + g_free(priv->root_uri); + priv->root_uri=NULL; + } } gboolean plover_package_set_open(PloverPackageSet *set,const char *root_uri, gboolean exclusive,GError **err) { + gboolean incompatible_lock=FALSE; struct razor_root *root=NULL; struct razor_set *system=NULL; PloverPackageSetPrivate *priv; struct razor_error *error=NULL; g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE); g_return_val_if_fail(plover__uri_validate(root_uri),FALSE); + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); + /* + * If we're opening a different root_uri, then we can simply open the + * new root first and then close the old root if we're successful. + * Otherwise, if we're changing the lock type we have to close the + * old lock first which allows for the possibility of failing to + * re-open the old root on failure. That's unfortunate but appears + * unavoidable; MS-Windows doesn't appear to have the ability to + * either upgrade or downgrade a file lock. + */ + if (!g_strcmp0(root_uri,priv->root_uri)) + { + incompatible_lock=!priv->root!=!exclusive; + if (incompatible_lock) + plover_package_set_close(set); + else + return TRUE; + } if (exclusive) { root=razor_root_open(root_uri,NULL); @@ -150,6 +169,8 @@ if (!root) { plover_propagate_razor_error(err,error); + if (incompatible_lock) + (void)plover_package_set_open(set,root_uri,!exclusive,NULL); return FALSE; } } @@ -164,23 +185,14 @@ g_set_error_literal(err,PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED, razor_error_get_msg(error)); razor_error_free(error); + if (incompatible_lock) + (void)plover_package_set_open(set,root_uri,!exclusive,NULL); return FALSE; } - priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); - if (priv->set) - { - razor_set_unref(priv->set); - priv->set=NULL; - } - if (priv->root) - { - razor_root_close(priv->root); - priv->root=NULL; - } - g_free(priv->root_uri); - priv->root_uri=g_strdup(root_uri); + plover_package_set_close(set); priv->root=root; priv->set=system; + priv->root_uri=g_strdup(root_uri); return TRUE; }