controller: use a lock for accessing Repositories. Fixes rare crashes when multiple threads want access
This commit is contained in:
parent
aa610c818e
commit
35a7c13422
|
@ -34,7 +34,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public abstract class SparkleControllerBase {
|
public abstract class SparkleControllerBase {
|
||||||
|
|
||||||
public List <SparkleRepoBase> Repositories;
|
public List<SparkleRepoBase> Repositories = new List<SparkleRepoBase> ();
|
||||||
public readonly string SparklePath = SparkleConfig.DefaultConfig.FoldersPath;
|
public readonly string SparklePath = SparkleConfig.DefaultConfig.FoldersPath;
|
||||||
|
|
||||||
public double ProgressPercentage = 0.0;
|
public double ProgressPercentage = 0.0;
|
||||||
|
@ -93,6 +93,7 @@ namespace SparkleShare {
|
||||||
private List<string> failed_avatars = new List<string> ();
|
private List<string> failed_avatars = new List<string> ();
|
||||||
|
|
||||||
private Object avatar_lock = new Object ();
|
private Object avatar_lock = new Object ();
|
||||||
|
private Object repo_lock = new Object ();
|
||||||
|
|
||||||
|
|
||||||
// Short alias for the translations
|
// Short alias for the translations
|
||||||
|
@ -200,10 +201,12 @@ namespace SparkleShare {
|
||||||
get {
|
get {
|
||||||
List<string> unsynced_folders = new List<string> ();
|
List<string> unsynced_folders = new List<string> ();
|
||||||
|
|
||||||
foreach (SparkleRepoBase repo in Repositories) {
|
lock (this.repo_lock) {
|
||||||
if (repo.HasUnsyncedChanges)
|
foreach (SparkleRepoBase repo in Repositories) {
|
||||||
unsynced_folders.Add (repo.Name);
|
if (repo.HasUnsyncedChanges)
|
||||||
}
|
unsynced_folders.Add (repo.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return unsynced_folders;
|
return unsynced_folders;
|
||||||
}
|
}
|
||||||
|
@ -236,13 +239,15 @@ namespace SparkleShare {
|
||||||
{
|
{
|
||||||
List<SparkleChangeSet> list = new List<SparkleChangeSet> ();
|
List<SparkleChangeSet> list = new List<SparkleChangeSet> ();
|
||||||
|
|
||||||
foreach (SparkleRepoBase repo in Repositories) {
|
lock (this.repo_lock) {
|
||||||
List<SparkleChangeSet> change_sets = repo.GetChangeSets (30);
|
foreach (SparkleRepoBase repo in Repositories) {
|
||||||
|
List<SparkleChangeSet> change_sets = repo.GetChangeSets (30);
|
||||||
if (change_sets != null)
|
|
||||||
list.AddRange (change_sets);
|
if (change_sets != null)
|
||||||
else
|
list.AddRange (change_sets);
|
||||||
SparkleHelpers.DebugInfo ("Log", "Could not create log for " + repo.Name);
|
else
|
||||||
|
SparkleHelpers.DebugInfo ("Log", "Could not create log for " + repo.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
|
list.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
|
||||||
|
@ -262,10 +267,12 @@ namespace SparkleShare {
|
||||||
|
|
||||||
string path = Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, name);
|
string path = Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, name);
|
||||||
int log_size = 50;
|
int log_size = 50;
|
||||||
|
|
||||||
foreach (SparkleRepoBase repo in Repositories) {
|
lock (this.repo_lock) {
|
||||||
if (repo.LocalPath.Equals (path))
|
foreach (SparkleRepoBase repo in Repositories) {
|
||||||
return repo.GetChangeSets (log_size);
|
if (repo.LocalPath.Equals (path))
|
||||||
|
return repo.GetChangeSets (log_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -553,19 +560,20 @@ namespace SparkleShare {
|
||||||
bool has_syncing_repos = false;
|
bool has_syncing_repos = false;
|
||||||
bool has_unsynced_repos = false;
|
bool has_unsynced_repos = false;
|
||||||
|
|
||||||
foreach (SparkleRepoBase repo in Repositories) {
|
lock (this.repo_lock) {
|
||||||
if (repo.Status == SyncStatus.SyncDown ||
|
foreach (SparkleRepoBase repo in Repositories) {
|
||||||
repo.Status == SyncStatus.SyncUp ||
|
if (repo.Status == SyncStatus.SyncDown ||
|
||||||
repo.IsBuffering) {
|
repo.Status == SyncStatus.SyncUp ||
|
||||||
|
repo.IsBuffering) {
|
||||||
has_syncing_repos = true;
|
|
||||||
|
has_syncing_repos = true;
|
||||||
} else if (repo.HasUnsyncedChanges) {
|
|
||||||
has_unsynced_repos = true;
|
} else if (repo.HasUnsyncedChanges) {
|
||||||
|
has_unsynced_repos = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (has_syncing_repos) {
|
if (has_syncing_repos) {
|
||||||
if (OnSyncing != null)
|
if (OnSyncing != null)
|
||||||
OnSyncing ();
|
OnSyncing ();
|
||||||
|
@ -646,7 +654,10 @@ namespace SparkleShare {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Repositories.Add (repo);
|
lock (this.repo_lock) {
|
||||||
|
Repositories.Add (repo);
|
||||||
|
}
|
||||||
|
|
||||||
repo.Initialize ();
|
repo.Initialize ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,14 +668,16 @@ namespace SparkleShare {
|
||||||
{
|
{
|
||||||
string folder_name = Path.GetFileName (folder_path);
|
string folder_name = Path.GetFileName (folder_path);
|
||||||
|
|
||||||
for (int i = 0; i < Repositories.Count; i++) {
|
lock (this.repo_lock) {
|
||||||
SparkleRepoBase repo = Repositories [i];
|
for (int i = 0; i < Repositories.Count; i++) {
|
||||||
|
SparkleRepoBase repo = Repositories [i];
|
||||||
if (repo.Name.Equals (folder_name)) {
|
|
||||||
repo.Dispose ();
|
if (repo.Name.Equals (folder_name)) {
|
||||||
Repositories.Remove (repo);
|
repo.Dispose ();
|
||||||
repo = null;
|
Repositories.Remove (repo);
|
||||||
break;
|
repo = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,8 +687,6 @@ namespace SparkleShare {
|
||||||
// folders in the SparkleShare folder
|
// folders in the SparkleShare folder
|
||||||
private void PopulateRepositories ()
|
private void PopulateRepositories ()
|
||||||
{
|
{
|
||||||
Repositories = new List<SparkleRepoBase> ();
|
|
||||||
|
|
||||||
foreach (string folder_name in SparkleConfig.DefaultConfig.Folders) {
|
foreach (string folder_name in SparkleConfig.DefaultConfig.Folders) {
|
||||||
string folder_path = new SparkleFolder (folder_name).FullPath;
|
string folder_path = new SparkleFolder (folder_name).FullPath;
|
||||||
|
|
||||||
|
@ -1077,12 +1088,14 @@ namespace SparkleShare {
|
||||||
// quits if safe
|
// quits if safe
|
||||||
public void TryQuit ()
|
public void TryQuit ()
|
||||||
{
|
{
|
||||||
foreach (SparkleRepoBase repo in Repositories) {
|
lock (this.repo_lock) {
|
||||||
if (repo.Status == SyncStatus.SyncUp ||
|
foreach (SparkleRepoBase repo in Repositories) {
|
||||||
repo.Status == SyncStatus.SyncDown ||
|
if (repo.Status == SyncStatus.SyncUp ||
|
||||||
repo.IsBuffering) {
|
repo.Status == SyncStatus.SyncDown ||
|
||||||
|
repo.IsBuffering) {
|
||||||
return;
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,8 +1105,10 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public void Quit ()
|
public void Quit ()
|
||||||
{
|
{
|
||||||
foreach (SparkleRepoBase repo in Repositories)
|
lock (this.repo_lock) {
|
||||||
repo.Dispose ();
|
foreach (SparkleRepoBase repo in Repositories)
|
||||||
|
repo.Dispose ();
|
||||||
|
}
|
||||||
|
|
||||||
Environment.Exit (0);
|
Environment.Exit (0);
|
||||||
}
|
}
|
||||||
|
@ -1104,9 +1119,11 @@ namespace SparkleShare {
|
||||||
folder_name = folder_name.Replace ("%20", " ");
|
folder_name = folder_name.Replace ("%20", " ");
|
||||||
note = note.Replace ("%20", " ");
|
note = note.Replace ("%20", " ");
|
||||||
|
|
||||||
foreach (SparkleRepoBase repo in Repositories) {
|
lock (this.repo_lock) {
|
||||||
if (repo.Name.Equals (folder_name))
|
foreach (SparkleRepoBase repo in Repositories) {
|
||||||
repo.AddNote (revision, note);
|
if (repo.Name.Equals (folder_name))
|
||||||
|
repo.AddNote (revision, note);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue