#define USE_CLIENT_POOL
#include "server.h"

/*  Same as demo.c but instead of handling clients serially, a pool of clients
 *  is handled in the same fashion.  The slight difference may allow more
 *  throughput at the cost of a tiny bit more memory and a tiny bit slowdown
 *  due to the requirement to remember multiple client states and higher CPU
 *  usage.  
 *
 *  [!] The attack surface of the interface is increased as well so an
 *  adversarial client can now cause denial of service attacks by opening
 *  and closing a connection making this demo needing to recalculate client
 *  state.  In addition if state is not calculated well, eg: the fractional time
 *  resolution is not good enough, an adversary could either cause the client
 *  pool to be always full or always empty.  Yay!
 */
int main(int argc, char *argv[]) {
    int sock;
    client pool[POOL_SIZE];

    #ifdef _WIN32
    // if compiling on Msft include the winsock librariy (ws2_32.lib)
    WSADATA wsaData;
    if(msftVendorLockInCode(&wsaData)) return 1;
    #endif

    // terminate if we cannot get a socket that can be used to accept clients
    if(!(sock = setup())) return 1;

    // initialize client pool
    for(uint32_t i = 0; i < POOL_SIZE; i++) pool[i].fd = -1;
    // server listen port is first socket file descriptor
    pool[0].fd = sock;

    while(1) {
        if(!faceItMetal(1000 /* ms */, alwaysGood, pool)) return softCuteBunnies(1);
    }

    return softCuteBunnies(0);
}
