2020-09-29 17:18:53 +00:00
|
|
|
module tristanable.manager;
|
|
|
|
|
2020-09-29 17:13:36 +00:00
|
|
|
import std.socket : Socket;
|
|
|
|
import core.sync.mutex : Mutex;
|
|
|
|
import bmessage : bSendMessage = sendMessage;
|
2020-09-29 17:18:53 +00:00
|
|
|
import tristanable.queue : Queue;
|
2020-10-16 15:11:26 +00:00
|
|
|
import tristanable.watcher;
|
2021-09-08 09:14:03 +00:00
|
|
|
import std.container.dlist;
|
2020-09-29 17:13:36 +00:00
|
|
|
|
2020-09-29 09:57:25 +00:00
|
|
|
public final class Manager
|
|
|
|
{
|
|
|
|
/* All queues */
|
2021-09-08 09:14:03 +00:00
|
|
|
private DList!(Queue) queues;
|
2020-09-29 09:57:25 +00:00
|
|
|
private Mutex queuesLock;
|
|
|
|
|
|
|
|
/* TODO Add drop queue? */
|
|
|
|
|
2020-09-29 17:13:36 +00:00
|
|
|
/**
|
|
|
|
* The remote host
|
|
|
|
*/
|
|
|
|
private Socket socket;
|
|
|
|
|
|
|
|
|
2020-10-16 15:11:26 +00:00
|
|
|
private Watcher watcher;
|
|
|
|
|
2020-09-29 17:13:36 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructs a new Manager with the given
|
|
|
|
* endpoint Socket
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
this(Socket socket)
|
2020-09-29 09:57:25 +00:00
|
|
|
{
|
2020-09-29 17:13:36 +00:00
|
|
|
/* Set the socket */
|
|
|
|
this.socket = socket;
|
|
|
|
|
|
|
|
/* Initialize the queues mutex */
|
|
|
|
queuesLock = new Mutex();
|
|
|
|
|
|
|
|
/* Initialize the watcher */
|
2020-10-16 15:11:26 +00:00
|
|
|
watcher = new Watcher(this, socket);
|
|
|
|
|
2020-09-29 09:57:25 +00:00
|
|
|
}
|
|
|
|
|
2020-09-29 17:13:36 +00:00
|
|
|
public Queue getQueue(ulong tag)
|
|
|
|
{
|
|
|
|
Queue matchingQueue;
|
|
|
|
|
|
|
|
queuesLock.lock();
|
|
|
|
|
|
|
|
foreach(Queue queue; queues)
|
|
|
|
{
|
|
|
|
if(queue.getTag() == tag)
|
|
|
|
{
|
|
|
|
matchingQueue = queue;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
queuesLock.unlock();
|
|
|
|
|
|
|
|
return matchingQueue;
|
|
|
|
}
|
2020-09-29 09:57:25 +00:00
|
|
|
|
2021-09-08 11:46:05 +00:00
|
|
|
/* TODO: Probably remove this or keep it */
|
|
|
|
public bool isValidTag(ulong tag)
|
|
|
|
{
|
|
|
|
return !(getQueue(tag) is null);
|
|
|
|
}
|
|
|
|
|
2021-09-08 11:40:39 +00:00
|
|
|
/**
|
|
|
|
* Returns a new queue with a new ID,
|
|
|
|
* if all IDs are used then it returns
|
|
|
|
* null
|
|
|
|
*
|
|
|
|
* Use this if you don't care about reserving
|
|
|
|
* queues IDs and just want a throwaway queue
|
2021-09-08 11:46:05 +00:00
|
|
|
*
|
|
|
|
* FIXME: All tags in use, this won't handle it
|
2021-09-08 11:40:39 +00:00
|
|
|
*/
|
|
|
|
public Queue generateQueue()
|
|
|
|
{
|
|
|
|
/* Newly generated queue */
|
|
|
|
Queue newQueue;
|
|
|
|
|
|
|
|
queuesLock.lock();
|
|
|
|
|
|
|
|
ulong curGuess = 0;
|
|
|
|
bool bad = true;
|
|
|
|
reguess: while(bad)
|
|
|
|
{
|
2021-09-08 11:47:53 +00:00
|
|
|
if(isValidTag(curGuess))
|
2021-09-08 11:40:39 +00:00
|
|
|
{
|
2021-09-08 11:47:53 +00:00
|
|
|
curGuess++;
|
|
|
|
continue reguess;
|
2021-09-08 11:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bad = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the new queue with the free id found */
|
|
|
|
newQueue = new Queue(curGuess);
|
|
|
|
|
2021-09-08 11:42:25 +00:00
|
|
|
/* Add the queue (recursive mutex) */
|
|
|
|
addQueue(newQueue);
|
2021-09-08 11:40:39 +00:00
|
|
|
|
|
|
|
queuesLock.unlock();
|
|
|
|
|
|
|
|
|
|
|
|
return newQueue;
|
|
|
|
}
|
|
|
|
|
2021-09-08 17:21:33 +00:00
|
|
|
public Queue[] getQueues()
|
|
|
|
{
|
|
|
|
Queue[] queues;
|
|
|
|
queuesLock.lock();
|
|
|
|
|
|
|
|
foreach(Queue queue; this.queues)
|
|
|
|
{
|
|
|
|
queues ~= queue;
|
|
|
|
}
|
|
|
|
|
|
|
|
queuesLock.unlock();
|
|
|
|
|
|
|
|
return queues;
|
|
|
|
}
|
|
|
|
|
2021-09-08 12:24:58 +00:00
|
|
|
public void removeQueue(Queue queue)
|
|
|
|
{
|
|
|
|
queuesLock.lock();
|
|
|
|
|
|
|
|
/* Make sure such a tag exists */
|
|
|
|
if(isValidTag(queue.getTag()))
|
|
|
|
{
|
|
|
|
queues.linearRemoveElement(queue);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* TODO: Throw an error here */
|
|
|
|
}
|
|
|
|
|
|
|
|
queuesLock.unlock();
|
|
|
|
}
|
|
|
|
|
2020-09-29 17:13:36 +00:00
|
|
|
public void addQueue(Queue queue)
|
2020-09-29 09:57:25 +00:00
|
|
|
{
|
2020-09-29 17:13:36 +00:00
|
|
|
queuesLock.lock();
|
|
|
|
|
|
|
|
/* Make sure such a tag does not exist already */
|
2021-09-08 11:46:38 +00:00
|
|
|
if(!isValidTag(queue.getTag()))
|
2020-09-29 17:13:36 +00:00
|
|
|
{
|
|
|
|
queues ~= queue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* TODO: Throw an error here */
|
|
|
|
}
|
|
|
|
|
|
|
|
queuesLock.unlock();
|
2020-09-29 09:57:25 +00:00
|
|
|
}
|
|
|
|
|
2021-09-08 11:46:05 +00:00
|
|
|
/**
|
|
|
|
* TODO: Comment
|
|
|
|
* TODO: Testing
|
|
|
|
*/
|
2020-09-29 17:13:36 +00:00
|
|
|
public void shutdown()
|
|
|
|
{
|
|
|
|
/* TODO: Implement me */
|
2021-09-08 09:19:05 +00:00
|
|
|
|
|
|
|
/* Make the loop stop whenever it does */
|
|
|
|
watcher.shutdown();
|
|
|
|
|
|
|
|
/* Wait for the thread to end */
|
|
|
|
watcher.join();
|
2020-09-29 17:13:36 +00:00
|
|
|
}
|
2020-09-29 09:57:25 +00:00
|
|
|
}
|