Returning back with a solution you might want to consider implementing.
My solution uses Java, and since Java is benefitted with syncronized methods and volatile variables, if you are considering porting my code into C or any other programming language obviously you’re going to have to use a mutex to lock the variable directly, or consider a counting lock. Just make sure you know what atomic instructions are.
class MessageSender implements Runnable{
public static volatile int flood = 0;
public static final int FLOOD_LIMIT = 100;
private BotController botController; //This is another class I created which controls my bot
private String message;
public synchronized static void decrementFlood(){
flood -= 1;
System.out.println("[Decremented] Flood: " + flood);
}
public synchronized static void incrementFlood(BotController botController, String message){
flood += 1;
botController.getBot().send().message(botController.CHANNEL, message);
System.out.println("[Incremented] Flood: " + flood);
}
public MessageSender(BotController botController, String message) {
//This is just a constructor
this.botController = botController;
this.message = message;
}
@Override
public void run() {
if (flood == FLOOD_LIMIT){
while(flood == FLOOD_LIMIT){
try{
Thread.sleep(1000); //Can be replaced with executor services to determine when threads end
} catch (InterruptedException ex ){
System.out.println("Interrupted Thread error, this would imply you aborted the program.");
}
}
}
incrementFlood(botController, message);
Thread decrementThread = new Thread(new GameTimer(30, true)); //This is just a timer I made to count to 30 and then decrement
decrementThread.start();
}
}
I made this class, designed to be executed through a thread or thread pool (hence why I implemented Runnable)
So here’s my implementiation:
public static void sendMessage(BotController botController, String message){
Thread messageThread = new Thread(new MessageSender(botController, message));
messageThread.start();
}
I ran tests already with this and it works well. You could probably further upgrade my example by creating a fixed size thread pool of 100, and cast jobs of sending messages on them, waiting 30 seconds, and terminating them. You could then possibly handle the thread pool with an executor service, which might be beneficial if you want to know exactly when your threads exit, rather than sleep-waiting for threads to finish. The reason I chose to sleep-wait is because it far less CPU output than an executor, event driven listening service.
Toodles.