]> git.ozlabs.org Git - ccan-lca-2011.git/blobdiff - ccan/oserver/oserver.c
lca2011: use max_clients field to control dynamic length of clients array.
[ccan-lca-2011.git] / ccan / oserver / oserver.c
index 362bfae849fc2ec8aef9c951fc1d3f5b9cd7ef2b..9fb7ebb9442d15fb74c3bb0d0ba13e26ccb15f9a 100644 (file)
@@ -87,7 +87,7 @@ static bool get_subclient(struct client *me)
 {
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(me->oserver->clients); i++) {
+       for (i = 0; i < me->oserver->max_clients; i++) {
                struct client *c = me->oserver->clients[i];
                if (!c || c == me)
                        continue;
@@ -104,7 +104,7 @@ static bool get_oracle(struct client *me)
 {
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(me->oserver->clients); i++) {
+       for (i = 0; i < me->oserver->max_clients; i++) {
                struct client *c = me->oserver->clients[i];
                if (!c || c == me)
                        continue;
@@ -223,15 +223,21 @@ static int cleanup_client(struct client *client)
        return 0;
 }
 
-static unsigned int max_client(struct client *clients[5])
+static unsigned int find_id(struct oserver *oserver)
 {
-       unsigned int i, ret = 0;
+       unsigned int id;
 
-       for (i = 0; i < 5; i++) {
-               if (clients[i])
-                       ret = i+1;
+       for (id = 0; id < oserver->max_clients; id++) {
+               if (oserver->clients[id] == NULL)
+                       return id;
        }
-       return ret;
+
+       /* Enlarge. */
+       oserver->clients = talloc_realloc(oserver,
+                                         oserver->clients,
+                                         struct client *,
+                                         ++oserver->max_clients);
+       return id;
 }
 
 static void add_client(struct tevent_context *ev,
@@ -257,21 +263,8 @@ static void add_client(struct tevent_context *ev,
                                    service_client, client);
        tevent_fd_set_auto_close(client->fde);
 
-       /* Find empty slot in array for this client. */
-       for (client->id = 0; oserver->clients[client->id]; client->id++);
+       client->id = find_id(oserver);
        oserver->clients[client->id] = client;
-       talloc_set_destructor(client, cleanup_client);
-
-       /* Full?  Stop listening... */
-       if (client->id == ARRAY_SIZE(oserver->clients)-1)
-               tevent_fd_set_flags(oserver->fde, 0);
-       oserver->max_clients = max_client(oserver->clients);
-}
-
-static void clear_clients(struct oserver *oserver)
-{
-       memset(oserver->clients, 0,
-              ARRAY_SIZE(oserver->clients) * sizeof(oserver->clients[0]));
 }
 
 static int destroy_oserver(struct oserver *oserver)
@@ -343,8 +336,6 @@ static bool load_file(struct oserver *oserver, const char *file)
 static bool complete_server(struct tevent_context *ev,
                            struct oserver *oserver, const char *dumpfile)
 {
-       oserver->max_clients = max_client(oserver->clients);
-
        /* Re-set this even if restored from file, in case it changed. */
        oserver->dumpfile = dumpfile;
        if (oserver->dumpfile)
@@ -375,7 +366,7 @@ struct oserver *oserver_restore(struct tevent_context *ev, const char *dumpfile)
        }
 
        /* Restore ignored fields in clients, and talloc hierarchy. */
-       for (i = 0; i < ARRAY_SIZE(oserver->clients); i++) {
+       for (i = 0; i < oserver->max_clients; i++) {
                struct client *client = oserver->clients[i];
                if (!client)
                        continue;
@@ -419,7 +410,8 @@ struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
                     oserver->argv_len++);
        } else
                oserver->argv_len = 0;
-       clear_clients(oserver);
+       oserver->max_clients = 0;
+       oserver->clients = NULL;
        oserver->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (oserver->fd < 0) {
                talloc_free(oserver);