| 807 | demo_s demos[MAXDEMOS]; |
| 808 | |
| 809 | demo_s *initdemoslot() // fetch empty demo slot, clean up surplus slots |
| 810 | { |
| 811 | static int demosequencecounter = 0, lastdemoslot = 0; |
| 812 | const int demosequencewraparound = max(126, MAXDEMOS * 4); |
| 813 | ASSERT(ismainthread() && MAXDEMOS < 126); |
| 814 | for(;;) |
| 815 | { |
| 816 | int used = 0; |
| 817 | loopi(MAXDEMOS) if(demos[i].sequence) used++; |
| 818 | if(used >= demo_max_number) |
| 819 | { // drop old demos (oldest sequence counters first) |
| 820 | int oldestage = -1, oldestdemo; |
| 821 | loopi(MAXDEMOS) if(demos[i].sequence) |
| 822 | { |
| 823 | int age = (demosequencecounter - demos[i].sequence + demosequencewraparound) % demosequencewraparound; |
| 824 | if(age > oldestage) |
| 825 | { |
| 826 | oldestage = age; |
| 827 | oldestdemo = i; |
| 828 | } |
| 829 | } |
| 830 | if(oldestage >= 0) |
| 831 | { |
| 832 | demo_s &c = demos[oldestdemo]; |
| 833 | mlog(ACLOG_VERBOSE, "dropping demo #%d \"%s\", age %d", c.sequence, c.info, oldestage); |
| 834 | if(!c.done) mlog(ACLOG_ERROR, "clearing unfinished demo slot #%d, probably leaked some memory...", c.sequence); |
| 835 | else DELETEA(c.data); |
| 836 | c.rb = NULL; |
| 837 | c.db = NULL; |
| 838 | c.data = NULL; |
| 839 | c.tigerstate = NULL; |
| 840 | c.gz = c.dbs = NULL; |
| 841 | c.sequence = 0; |
| 842 | } |
| 843 | } |
| 844 | else break; |
| 845 | } |
| 846 | demo_s *d = NULL; |
| 847 | int n; |
| 848 | loopi(MAXDEMOS) if(!demos[(n = (i + lastdemoslot) % MAXDEMOS)].sequence) { d = demos + n; lastdemoslot = n + 1; break; } |
| 849 | ASSERT(d != NULL); |
| 850 | d->clients_waiting.setsize(0); |
| 851 | d->clients_served.setsize(0); |
| 852 | d->rb = demoringbuf_store.length() ? demoringbuf_store.remove() : new demoringbuf; |
| 853 | d->db = demobuf_store.length() ? demobuf_store.remove() : new demobuf; |
| 854 | DELETEA(d->data); |
| 855 | d->rb->clear(); |
| 856 | d->db->setsize(0); |
| 857 | d->len = 0; |
| 858 | d->tigerstate = tigerhash_init(d->tiger); |
| 859 | d->dbs = openvecfile(d->db, false); // no autodelete: we'll keep db allocated |
| 860 | d->gz = opengzfile(NULL, "wb", d->dbs); |
| 861 | d->remove = d->finish = d->error = d->done = false; |
| 862 | for(bool tryagain = true; tryagain; ) |
| 863 | { // get unique sequence number (brute force) |
| 864 | demosequencecounter = (d->sequence = (demosequencecounter + 1)) % demosequencewraparound; |
| 865 | tryagain = false; |
| 866 | loopi(MAXDEMOS) if(demos[i].sequence == d->sequence && demos + i != d) tryagain = true; |
no test coverage detected