Remove unnecessary parts of the MainLoop code.

This commit is contained in:
UnknownShadow200 2016-05-19 13:39:39 +10:00
parent 89f3b9d68d
commit abcbe79eb3
6 changed files with 30 additions and 381 deletions

View File

@ -621,10 +621,7 @@
<Compile Include="util\ExtrasCollection.cs" />
<Compile Include="Network\ClassiCube.cs" />
<Compile Include="properties\AssemblyInfo.cs" />
<Compile Include="queue\Cache.cs" />
<Compile Include="queue\ICacheable.cs" />
<Compile Include="queue\MainLoop.cs" />
<Compile Include="queue\TorrentException.cs" />
<Compile Include="util\Extensions.cs" />
<Compile Include="util\Hasher.cs" />
<Compile Include="util\ICryptoService.cs" />

View File

@ -422,9 +422,8 @@ namespace MCGalaxy
public static MainLoop ml;
public static Server s;
public Server()
{
ml = new MainLoop("server");
public Server() {
ml = new MainLoop("MCG_Scheduler");
Server.s = this;
}
//True = cancel event

View File

@ -1,109 +0,0 @@
//
// Cache.cs
//
// Authors:
// Alan McGovern alan.mcgovern@gmail.com
//
// Copyright (C) 2009 Alan McGovern
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
namespace MonoTorrent.Common
{
interface ICache<T>
{
int Count { get; }
T Dequeue();
void Enqueue(T instance);
}
sealed class Cache<T> : ICache<T>
where T : class, ICacheable, new()
{
bool autoCreate;
Queue<T> cache;
public int Count
{
get { return cache.Count; }
}
public Cache()
: this(false)
{
}
public Cache(bool autoCreate)
{
this.autoCreate = autoCreate;
this.cache = new Queue<T>();
}
public T Dequeue()
{
if (cache.Count > 0)
return cache.Dequeue();
return autoCreate ? new T() : null;
}
public void Enqueue(T instance)
{
instance.Initialise();
cache.Enqueue(instance);
}
public ICache<T> Synchronize()
{
return new SynchronizedCache<T>(this);
}
}
sealed class SynchronizedCache<T> : ICache<T>
{
ICache<T> cache;
public int Count
{
get { return cache.Count; }
}
public SynchronizedCache(ICache<T> cache)
{
if (cache == null)
throw new ArgumentNullException("cache");
this.cache = cache;
}
public T Dequeue()
{
lock (cache)
return cache.Dequeue();
}
public void Enqueue(T instance)
{
lock (cache)
cache.Enqueue(instance);
}
}
}

View File

@ -1,34 +0,0 @@
//
// ICacheable.cs
//
// Authors:
// Alan McGovern alan.mcgovern@gmail.com
//
// Copyright (C) 2008 Alan McGovern
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace MonoTorrent.Common
{
interface ICacheable
{
void Initialise();
}
}

View File

@ -28,216 +28,66 @@
using System;
using System.Collections.Generic;
using System.Threading;
using MonoTorrent.Common;
namespace MonoTorrent.Client
{
namespace MonoTorrent.Client {
public delegate void MainLoopResult(object result);
public delegate object MainLoopJob();
public delegate void MainLoopTask();
public delegate bool TimeoutTask();
public sealed class MainLoop
{
private class DelegateTask : ICacheable
{
private ManualResetEvent handle;
private bool isBlocking;
private MainLoopJob job;
private object jobResult;
private Exception storedException;
private MainLoopTask task;
private TimeoutTask timeout;
private bool timeoutResult;
public sealed class MainLoop {
private class SchedulerTask {
public Exception StoredException;
public MainLoopTask Task;
public bool IsBlocking
{
get { return isBlocking; }
set { isBlocking = value; }
}
public MainLoopJob Job
{
get { return job; }
set { job = value; }
}
public Exception StoredException
{
get { return storedException; }
set { storedException = value; }
}
public MainLoopTask Task
{
get { return task; }
set { task = value; }
}
public TimeoutTask Timeout
{
get { return timeout; }
set { timeout = value; }
}
public object JobResult
{
get { return jobResult; }
}
public bool TimeoutResult
{
get { return timeoutResult; }
}
public ManualResetEvent WaitHandle
{
get { return handle; }
}
public DelegateTask()
{
handle = new ManualResetEvent(false);
}
public void Execute()
{
try
{
if (job != null)
jobResult = job();
else if (task != null)
task();
else if (timeout != null)
timeoutResult = timeout();
public void Execute() {
try {
Task();
} catch (Exception ex) {
StoredException = ex;
throw;
}
catch (Exception ex)
{
storedException = ex;
// FIXME: I assume this case can't happen. The only user interaction
// with the mainloop is with blocking tasks. Internally it's a big bug
// if i allow an exception to propagate to the mainloop.
if (!IsBlocking)
throw;
}
finally
{
handle.Set();
}
}
public void Initialise()
{
isBlocking = false;
job = null;
jobResult = null;
storedException = null;
task = null;
timeout = null;
timeoutResult = false;
}
}
AutoResetEvent handle = new AutoResetEvent(false);
ICache<DelegateTask> cache = new Cache<DelegateTask>(true).Synchronize();
Queue<DelegateTask> tasks = new Queue<DelegateTask>();
Queue<SchedulerTask> tasks = new Queue<SchedulerTask>();
internal Thread thread;
public MainLoop(string name)
{
public MainLoop(string name) {
thread = new Thread(Loop);
thread.Name = "MCG_MainLoop";
thread.Name = name;
thread.IsBackground = true;
thread.Start();
}
void Loop()
{
while (true)
{
DelegateTask task = null;
lock (tasks)
{
void Loop() {
while (true) {
SchedulerTask task = null;
lock (tasks) {
if (tasks.Count > 0)
task = tasks.Dequeue();
}
if (task == null)
{
if (task == null) {
handle.WaitOne();
}
else
{
bool reuse = !task.IsBlocking;
} else {
task.Execute();
if (reuse)
cache.Enqueue(task);
}
Thread.Sleep(10);
}
}
private void Queue(DelegateTask task)
{
lock (tasks)
{
/// <summary> Queues an action that is asynchronously executed. </summary>
public void Queue(MainLoopTask action) {
SchedulerTask task = new SchedulerTask();
task.Task = action;
lock (tasks) {
tasks.Enqueue(task);
handle.Set();
}
}
public void Queue(MainLoopTask task)
{
DelegateTask dTask = cache.Dequeue();
dTask.Task = task;
Queue(dTask);
}
public void QueueWait(MainLoopTask task)
{
DelegateTask dTask = cache.Dequeue();
dTask.Task = task;
try
{
QueueWait(dTask);
}
finally
{
cache.Enqueue(dTask);
}
}
public object QueueWait(MainLoopJob task)
{
DelegateTask dTask = cache.Dequeue();
dTask.Job = task;
try
{
QueueWait(dTask);
return dTask.JobResult;
}
finally
{
cache.Enqueue(dTask);
}
}
private void QueueWait(DelegateTask t)
{
t.WaitHandle.Reset();
t.IsBlocking = true;
if (Thread.CurrentThread == thread)
t.Execute();
else
Queue(t);
t.WaitHandle.WaitOne();
if (t.StoredException != null)
throw new TorrentException("Exception in mainloop", t.StoredException);
}
}
}

View File

@ -1,54 +0,0 @@
//
// TorrentException.cs
//
// Authors:
// Alan McGovern alan.mcgovern@gmail.com
//
// Copyright (C) 2006 Alan McGovern
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
namespace MonoTorrent.Common
{
[Serializable]
public sealed class TorrentException : Exception
{
public TorrentException()
: base()
{
}
public TorrentException(string message)
: base(message)
{
}
public TorrentException(string message, Exception innerException)
: base(message, innerException)
{
}
public TorrentException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
: base(info, context)
{
}
}
}