diff --git a/src/alpm_utils.vala b/src/alpm_utils.vala index deedf11caa325c4a63b5b89a4532052992f3961c..0e869b7bed9525b97b72d3718e8ed37a7222b9dd 100644 --- a/src/alpm_utils.vala +++ b/src/alpm_utils.vala @@ -90,9 +90,10 @@ namespace Pamac { internal Alpm.Handle? alpm_handle; internal Alpm.Handle? files_handle; internal string tmp_path; - internal Cond provider_cond; - internal Mutex provider_mutex; + internal Cond alpm_cond; + internal Mutex alpm_mutex; internal int? choosen_provider; + internal bool? commit; internal bool force_refresh; internal int flags; GenericSet<string?> to_syncfirst; @@ -149,12 +150,65 @@ namespace Pamac { curl.setopt (Curl.Option.NETRC, Curl.NetRCOption.OPTIONAL); curl.setopt (Curl.Option.HTTPAUTH, Curl.CURLAUTH_ANY); downloading_updates = false; + check_old_lock (); } ~AlpmUtils () { Curl.global_cleanup (); } + void check_old_lock () { + var lockfile = GLib.File.new_for_path (alpm_handle.lockfile); + if (lockfile.query_exists ()) { + int exit_status; + string output; + uint64 lockfile_time; + try { + // get lockfile modification time since epoch + Process.spawn_command_line_sync ("stat -c %Y %s".printf (alpm_handle.lockfile), + out output, + null, + out exit_status); + if (exit_status == 0) { + string[] splitted = output.split ("\n"); + if (splitted.length == 2) { + if (uint64.try_parse (splitted[0], out lockfile_time)) { + uint64 boot_time; + // get boot time since epoch + Process.spawn_command_line_sync ("cat /proc/stat", + out output, + null, + out exit_status); + if (exit_status == 0) { + splitted = output.split ("\n"); + foreach (unowned string line in splitted) { + if ("btime" in line) { + string[] space_splitted = line.split (" "); + if (space_splitted.length == 2) { + if (uint64.try_parse (space_splitted[1], out boot_time)) { + // check if lock file is older than boot time + if (lockfile_time < boot_time) { + // remove the unneeded lock file. + try { + lockfile.delete (); + } catch (Error e) { + stderr.printf ("Error: %s\n", e.message); + } + } + } + } + } + } + } + } + } + } + } catch (SpawnError e) { + stderr.printf ("Error: %s\n", e.message); + } + } + } + internal void refresh_handle () { alpm_config = new AlpmConfig ("/etc/pacman.conf"); alpm_handle = alpm_config.get_handle (); @@ -391,9 +445,9 @@ namespace Pamac { syncdbs.next (); } int success = handle.trans_init (Alpm.TransFlag.DOWNLOADONLY); - // can't add nolock flag with commit so remove unneeded lock - handle.unlock (); if (success == 0) { + // can't add nolock flag with commit so remove unneeded lock + handle.unlock (); success = handle.trans_sysupgrade (0); if (success == 0) { Alpm.List err_data; @@ -818,6 +872,20 @@ namespace Pamac { trans_release (); } trans_prepare_finished (success); + if (success) { + // wait for a commit/release answer; + alpm_cond = Cond (); + alpm_mutex = Mutex (); + commit = null; + alpm_mutex.lock (); + while (commit == null) { + alpm_cond.wait (alpm_mutex); + } + alpm_mutex.unlock (); + if (commit) { + trans_commit (); + } + } } internal void build_prepare () { @@ -996,10 +1064,10 @@ namespace Pamac { } internal void choose_provider (int provider) { - provider_mutex.lock (); + alpm_mutex.lock (); choosen_provider = provider; - provider_cond.signal (); - provider_mutex.unlock (); + alpm_cond.signal (); + alpm_mutex.unlock (); } internal TransactionSummaryStruct get_transaction_summary () { @@ -1065,7 +1133,7 @@ namespace Pamac { queues_table = new HashTable<string, AsyncQueue<string>> (str_hash, str_equal); // get files to download total_download = 0; - unowned Alpm.List<unowned Alpm.Package> pkgs_to_add = alpm_utils.alpm_handle.trans_to_add (); + unowned Alpm.List<unowned Alpm.Package> pkgs_to_add = alpm_handle.trans_to_add (); while (pkgs_to_add != null) { unowned Alpm.Package trans_pkg = pkgs_to_add.data; uint64 download_size = trans_pkg.download_size; @@ -1086,13 +1154,13 @@ namespace Pamac { } // compute the dbs available for each mirror var mirrors_table = new HashTable<string, GenericSet<string>> (str_hash, str_equal); - unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_utils.alpm_handle.syncdbs; + unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs; while (syncdbs != null) { unowned Alpm.DB db = syncdbs.data; unowned Alpm.List<unowned string> servers = db.servers; while (servers != null) { unowned string server_full = servers.data; - string server = server_full.replace ("/%s".printf (alpm_utils.alpm_handle.arch), "").replace ("/%s".printf (db.name), ""); + string server = server_full.replace ("/%s".printf (alpm_handle.arch), "").replace ("/%s".printf (db.name), ""); if (mirrors_table.contains (server)) { unowned GenericSet<string> repos_set = mirrors_table.lookup (server); repos_set.add (db.name); @@ -1308,6 +1376,10 @@ namespace Pamac { } internal void trans_release () { + alpm_mutex.lock (); + commit = false; + alpm_cond.signal (); + alpm_mutex.unlock (); alpm_handle.trans_release (); remove_ignorepkgs (); remove_overwrite_files (); @@ -1461,16 +1533,16 @@ void cb_question (Alpm.Question.Data data) { providers_str += pkg.name; list.next (); } - alpm_utils.provider_cond = Cond (); - alpm_utils.provider_mutex = Mutex (); + alpm_utils.alpm_cond = Cond (); + alpm_utils.alpm_mutex = Mutex (); alpm_utils.choosen_provider = null; alpm_utils.emit_providers (depend_str, providers_str); - alpm_utils.provider_mutex.lock (); + alpm_utils.alpm_mutex.lock (); while (alpm_utils.choosen_provider == null) { - alpm_utils.provider_cond.wait (alpm_utils.provider_mutex); + alpm_utils.alpm_cond.wait (alpm_utils.alpm_mutex); } data.select_provider_use_index = alpm_utils.choosen_provider; - alpm_utils.provider_mutex.unlock (); + alpm_utils.alpm_mutex.unlock (); break; case Alpm.Question.Type.CORRUPTED_PKG: // Auto-remove corrupted pkgs in cache diff --git a/src/system_daemon.vala b/src/system_daemon.vala index f19de4c50361255b10c79f664387cd581616007a..759c5e5d7fdfb2b0a28ef0406b6b67a76e7b8492 100644 --- a/src/system_daemon.vala +++ b/src/system_daemon.vala @@ -78,7 +78,6 @@ namespace Pamac { // alpm_utils global variable declared in alpm_utils.vala alpm_utils = new AlpmUtils (config); lockfile = GLib.File.new_for_path (alpm_utils.alpm_handle.lockfile); - check_old_lock (); check_extern_lock (); Timeout.add (200, check_extern_lock); create_thread_pool (); @@ -105,15 +104,20 @@ namespace Pamac { emit_log (level, msg); }); alpm_utils.refresh_finished.connect ((success) => { + lock_id = new BusName (""); refresh_finished (success); }); alpm_utils.downloading_updates_finished.connect (() => { downloading_updates_finished (); }); alpm_utils.trans_prepare_finished.connect ((success) => { + if (!success) { + lock_id = new BusName (""); + } trans_prepare_finished (success); }); alpm_utils.trans_commit_finished.connect ((success) => { + lock_id = new BusName (""); database_modified (); trans_commit_finished (success); }); @@ -160,58 +164,6 @@ namespace Pamac { } } - private void check_old_lock () { - if (lockfile.query_exists ()) { - int exit_status; - string output; - uint64 lockfile_time; - try { - // get lockfile modification time since epoch - Process.spawn_command_line_sync ("stat -c %Y %s".printf (alpm_utils.alpm_handle.lockfile), - out output, - null, - out exit_status); - if (exit_status == 0) { - string[] splitted = output.split ("\n"); - if (splitted.length == 2) { - if (uint64.try_parse (splitted[0], out lockfile_time)) { - uint64 boot_time; - // get boot time since epoch - Process.spawn_command_line_sync ("cat /proc/stat", - out output, - null, - out exit_status); - if (exit_status == 0) { - splitted = output.split ("\n"); - foreach (unowned string line in splitted) { - if ("btime" in line) { - string[] space_splitted = line.split (" "); - if (space_splitted.length == 2) { - if (uint64.try_parse (space_splitted[1], out boot_time)) { - // check if lock file is older than boot time - if (lockfile_time < boot_time) { - // remove the unneeded lock file. - try { - lockfile.delete (); - } catch (Error e) { - stderr.printf ("Error: %s\n", e.message); - } - lock_id = new BusName (""); - } - } - } - } - } - } - } - } - } - } catch (SpawnError e) { - stderr.printf ("Error: %s\n", e.message); - } - } - } - private bool check_extern_lock () { if (lock_id == "extern") { if (!lockfile.query_exists ()) { @@ -230,20 +182,8 @@ namespace Pamac { return true; } - public bool get_lock (GLib.BusName sender) throws Error { - if (lock_id == sender) { - return true; - } else if (lock_id == "") { - lock_id = sender; - return true; - } - return false; - } - - public bool unlock (GLib.BusName sender) throws Error { - if (lock_id == sender) { - lock_id = new BusName (""); - authorized = false; + public bool get_lock () throws Error { + if (lock_id != "extern") { return true; } return false; @@ -376,7 +316,9 @@ namespace Pamac { bool authorized = check_authorization.end (res); bool success = false; if (authorized) { + lock_id = sender; success = alpm_utils.set_pkgreason (pkgname, reason); + lock_id = new BusName (""); } database_modified (); set_pkgreason_finished (success); @@ -384,10 +326,6 @@ namespace Pamac { } public void start_refresh (bool force, GLib.BusName sender) throws Error { - if (lock_id != sender) { - refresh_finished (false); - return; - } alpm_utils.force_refresh = force; if (alpm_utils.downloading_updates) { alpm_utils.cancellable.cancel (); @@ -396,6 +334,7 @@ namespace Pamac { check_authorization.begin (sender, (obj, res) => { bool authorized = check_authorization.end (res); if (authorized) { + lock_id = sender; launch_refresh_thread (); } else { refresh_finished (false); @@ -407,6 +346,7 @@ namespace Pamac { check_authorization.begin (sender, (obj, res) => { bool authorized = check_authorization.end (res); if (authorized) { + lock_id = sender; launch_refresh_thread (); } else { refresh_finished (false); @@ -433,10 +373,6 @@ namespace Pamac { string[] temporary_ignorepkgs, string[] overwrite_files, GLib.BusName sender) throws Error { - if (lock_id != sender) { - trans_prepare_finished (false); - return; - } alpm_utils.config.enable_downgrade = enable_downgrade; alpm_utils.temporary_ignorepkgs = temporary_ignorepkgs; alpm_utils.overwrite_files = overwrite_files; @@ -450,10 +386,12 @@ namespace Pamac { alpm_utils.cancellable.cancel (); // let time to cancel download updates Timeout.add (1000, () => { + lock_id = sender; launch_prepare_thread (); return false; }); } else { + lock_id = sender; launch_prepare_thread (); } } @@ -467,10 +405,6 @@ namespace Pamac { string[] overwrite_files, string[] to_mark_as_dep, GLib.BusName sender) throws Error { - if (lock_id != sender) { - trans_prepare_finished (false); - return; - } alpm_utils.flags = flags; alpm_utils.to_install = to_install; alpm_utils.to_remove = to_remove; @@ -484,10 +418,12 @@ namespace Pamac { alpm_utils.cancellable.cancel (); // let time to cancel download updates Timeout.add (1000, () => { + lock_id = sender; launch_prepare_thread (); return false; }); } else { + lock_id = sender; launch_prepare_thread (); } } @@ -523,13 +459,13 @@ namespace Pamac { check_authorization.begin (sender, (obj, res) => { bool authorized = check_authorization.end (res); if (authorized) { - try { - thread_pool.add (new AlpmAction (alpm_utils.trans_commit)); - } catch (ThreadError e) { - stderr.printf ("Thread Error %s\n", e.message); - } + alpm_utils.alpm_mutex.lock (); + alpm_utils.commit = true; + alpm_utils.alpm_cond.signal (); + alpm_utils.alpm_mutex.unlock (); } else { alpm_utils.trans_release (); + lock_id = new BusName (""); trans_commit_finished (false); } }); @@ -551,10 +487,6 @@ namespace Pamac { [DBus (no_reply = true)] public void quit () throws Error { - // do not quit if locked - if (lock_id != "" && lock_id != "extern"){ - return; - } // do not quit if downloading updates if (alpm_utils.downloading_updates) { return; diff --git a/src/transaction.vala b/src/transaction.vala index b4968bfdc563af6aea4ecdf4089453a67d62d6bb..4665065a3d0d276d48f3c597a2f2b66c895fe0e9 100644 --- a/src/transaction.vala +++ b/src/transaction.vala @@ -1305,7 +1305,6 @@ namespace Pamac { } else { finished (success); } - transaction_interface.unlock (); } void on_trans_prepare_finished (bool success) { diff --git a/src/transaction_interface.vala b/src/transaction_interface.vala index e9c63dfcde590359294a6833e1b505fd4dfaffd1..b2148acb4ba87d2e8cb02482b6bc72aa3f521be1 100644 --- a/src/transaction_interface.vala +++ b/src/transaction_interface.vala @@ -21,7 +21,6 @@ namespace Pamac { internal interface TransactionInterface : Object { public abstract ErrorInfos get_current_error (); public abstract bool get_lock (); - public abstract bool unlock (); public abstract void start_get_authorization (); public abstract void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf); public abstract void start_write_alpm_config (HashTable<string,Variant> new_alpm_conf); diff --git a/src/transaction_interface_daemon.vala b/src/transaction_interface_daemon.vala index 52c7a2426c54291d65755d3fe293a4edff10eb25..3777a5f50eb790a2c5b6edbcf30697b857faf143 100644 --- a/src/transaction_interface_daemon.vala +++ b/src/transaction_interface_daemon.vala @@ -23,7 +23,6 @@ namespace Pamac { public abstract void set_environment_variables (HashTable<string,string> variables) throws Error; public abstract ErrorInfos get_current_error () throws Error; public abstract bool get_lock () throws Error; - public abstract bool unlock () throws Error; public abstract void start_get_authorization () throws Error; public abstract void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf) throws Error; public abstract void start_write_alpm_config (HashTable<string,Variant> new_alpm_conf) throws Error; @@ -93,16 +92,6 @@ namespace Pamac { return locked; } - public bool unlock () { - bool unlocked = false; - try { - unlocked = system_daemon.unlock (); - } catch (Error e) { - stderr.printf ("unlock: %s\n", e.message); - } - return unlocked; - } - public void start_get_authorization () { try { system_daemon.start_get_authorization (); diff --git a/src/transaction_interface_root.vala b/src/transaction_interface_root.vala index f6f9840b63c1f4003c67d2165bc6bffaf2c7db35..75402939d8deb2cd88dab43f164f947036026319 100644 --- a/src/transaction_interface_root.vala +++ b/src/transaction_interface_root.vala @@ -67,12 +67,10 @@ namespace Pamac { } public bool get_lock () { - // we are root - return true; - } - - public bool unlock () { - // we are root + var lockfile = GLib.File.new_for_path (alpm_utils.alpm_handle.lockfile); + if (lockfile.query_exists ()) { + return false; + } return true; } @@ -269,13 +267,11 @@ namespace Pamac { return alpm_utils.get_transaction_summary (); } - int trans_commit () { - alpm_utils.trans_commit (); - return 0; - } - public void start_trans_commit () { - new Thread<int> ("trans_commit", trans_commit); + alpm_utils.alpm_mutex.lock (); + alpm_utils.commit = true; + alpm_utils.alpm_cond.signal (); + alpm_utils.alpm_mutex.unlock (); } public void trans_release () {