// stop background thread void datacloud::stopthread(int background) { int i; if (!ISNOTREADY) return; if (background==0) // stop all threads { signalthread(); for (i=1; i<=MAXTHREADS; i++) stopthread(i); } else // join thread if it is still running if (!ISREADY[background]) { SHOULDSTOP[background]=TRUE; JOIN_CALLBACK(&BACKARRAY[background],START_DATA); SHOULDSTOP[background]=FALSE; ISREADY[background]=TRUE; NUMTHREADS--; } if (NUMTHREADS==0) ISNOTREADY=FALSE; }
// signal background thread to finish void datacloud::signalthread(int background) { int i; if (!ISNOTREADY) return; if (background==0) // signal all threads to finish for (i=1; i<=MAXTHREADS; i++) signalthread(i); else // signal thread if it is still running if (!ISREADY[background]) SHOULDSTOP[background]=TRUE; }
// insert a tile into the cache tilecacheelem *datacloud::inserttile(const unsigned char *tileid,int col,int row,BOOLINT istexture,BOOLINT immediate,BOOLINT loprio,int lod) { tilecacheelem *oldtile,*newtile; // check for already existing tile oldtile=checktile(tileid,col,row,istexture,immediate,loprio,lod); // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // already existing tile if (oldtile!=NULL) { oldtile->refcount++; newtile=oldtile; } // allocate and initialize new tile else { newtile=new tilecacheelem; newtile->tileid=(unsigned char *)strdup((char *)tileid); newtile->tile=new databuf; newtile->col=col; newtile->row=row; newtile->istexture=istexture; newtile->loprio=loprio; newtile->lod=lod; newtile->refcount=1; newtile->isavailable=FALSE; newtile->isloading=FALSE; newtile->background=0; } // load immediate data if (immediate && !newtile->isavailable) { // signal background thread to finish signalthread(); // check if actual tile is already being loaded in the background if (newtile->isloading) { // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // wait for background thread to finish loading stopthread(newtile->background); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); } // load actual tile directly if (!newtile->isavailable) { // load in foreground loadtile(newtile); // decrease pending tile count if (oldtile!=NULL) PENDINGTILES--; } } // reset access time newtile->access=gettime(); newtile->isdelayed=FALSE; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // insert tile at cache tail if (oldtile==NULL) inserttile(TILECACHETAIL,newtile); return(newtile); }
// insert a tile into the cache tilecacheelem *datacloud::inserttile(unsigned char *tileid,int col,int row,BOOLINT istexture,BOOLINT immediate,BOOLINT loprio) { int i; tilecacheelem *oldtile,*newtile; // check for already existing tile oldtile=checktile(tileid,col,row,istexture,immediate,loprio); // already existing tile if (oldtile!=NULL) { newtile=oldtile; newtile->refcount++; } // allocate and initialize new tile else { newtile=new tilecacheelem; newtile->tileid=(unsigned char *)strdup((char *)tileid); newtile->tile=new databuf; newtile->col=col; newtile->row=row; newtile->istexture=istexture; newtile->loprio=loprio; newtile->refcount=1; newtile->isavailable=FALSE; newtile->isloading=FALSE; newtile->background=0; } // lock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // load immediate data if (immediate && !newtile->isavailable) { // signal background thread to finish signalthread(); // check if actual tile is already being loaded in the background if (newtile->isloading) { // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // wait for background thread to finish loading stopthread(newtile->background); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); } // load actual tile directly if (!newtile->isavailable) { // signal direct loading newtile->isloading=TRUE; // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // lock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) LOCKIO_CALLBACK(START_DATA); // load data REQUEST_CALLBACK(tileid,newtile->tile,istexture,0,REQUEST_DATA); // autocompress textures if (CONFIGURE_AUTOCOMPRESS!=0) newtile->tile->autocompress(); // unlock io if (ISNOTREADY) if (CONFIGURE_AUTOLOCKIO!=0) if (LOCKIO_CALLBACK!=NULL) UNLOCKIO_CALLBACK(START_DATA); // relock critical section if (ISNOTREADY) LOCK_CALLBACK(START_DATA); // signal availability newtile->isavailable=TRUE; newtile->isloading=FALSE; // decrease pending tile count if (oldtile!=NULL) PENDINGTILES--; } } // unlock critical section if (ISNOTREADY) UNLOCK_CALLBACK(START_DATA); // set access time newtile->access=minitime(); // insert tile at cache tail if (oldtile==NULL) inserttile(TILECACHETAIL,newtile); return(newtile); }