[mapguide-commits] r6160 - sandbox/rfc90.2/MgDev/Server/src/Services/Tile

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri Sep 30 06:55:36 EDT 2011


Author: uvlite
Date: 2011-09-30 03:55:36 -0700 (Fri, 30 Sep 2011)
New Revision: 6160

Modified:
   sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.cpp
   sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.h
   sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.vcproj
   sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.cpp
   sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.h
Log:
stable version with only minor leaks if any

Modified: sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.cpp
===================================================================
--- sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.cpp	2011-09-30 07:00:47 UTC (rev 6159)
+++ sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.cpp	2011-09-30 10:55:36 UTC (rev 6160)
@@ -19,6 +19,7 @@
 #include "ServerTileService.h"
 #include "ServerRenderingService.h"
 //#include <sstream>
+//#include <iostream>
 
 IMPLEMENT_CREATE_SERVICE(MgServerTileService)
 
@@ -83,8 +84,18 @@
             sm_initialized = true;
         }
     }
+
     m_tileCache = new MgTileCache(this);
     
+#ifdef _DEBUG
+    if (sm_useMetaTiles > 0)      // the tilecache is instantiated for each request so this is debug only
+    {
+        std::wstringstream text;
+        text << L"Server is using MetaTiling Factor: " << sm_useMetaTiles << L" & Locking Method: " << sm_lockMethod;
+        ACE_DEBUG ((LM_INFO, text.str().c_str()));
+
+    }
+#endif
     // bail out if metatile factor to large (allocation problem)
     if (sm_useMetaTiles > 7)
     {
@@ -117,32 +128,13 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief
-/// Detect if the tile file has been locked by another thread or process.
+/// Detect if the tile file has been locked by another thread or process and wait up to sm_creationCutoffTime
 ///
 bool MgServerTileService::DetectTileLockFile(CREFSTRING lockPathname, CREFSTRING tilePathname)
 {
     bool found = false;
     struct _stat lockFileInfo;
 
-    if (sm_lockMethod == 2) // simple collection of paths
-    {
-        int sec = sm_pollingInterval/1000;
-        ACE_Time_Value polInt (sec, (sm_pollingInterval - (sec*1000))*1000);
-        time_t startTime;
-        ACE_OS::time(&startTime);
-        time_t diffTime = 0;
-        time_t currTime;
-        // sm_creationCutoffTime times or found 
-        // TODO think about multithreaded lockmap access
-        //(found = m_tileCache->GetLockMap().count(tilePathname)) 
-        for (INT32 diffTime=0;diffTime < sm_creationCutoffTime; 
-             ACE_OS::time(&currTime),diffTime = (INT32)(currTime - startTime))
-        {   
-            // sm_pollingInterval om milliseconds
-            ACE_OS::sleep(polInt);
-        }
-    }
-
     // Check the lock file to see if another thread/process is writing the tile file.
     while (MgFileUtil::GetFileStatus(lockPathname, lockFileInfo))
     {
@@ -152,10 +144,12 @@
 
         if (diffTime < sm_creationCutoffTime)
         {
-            // sm_pollingInterval om milliseconds
-            int sec = sm_pollingInterval/1000;
-            ACE_Time_Value polInt (sec, (sm_pollingInterval - (sec*1000))*1000);
-            ACE_OS::sleep(polInt);
+            ACE_OS::sleep(sm_pollingInterval);
+#ifdef _DEBUG
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: WaitForLockfile(" << lockPathname << L")\n" ;
+            ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
+#endif
         }
         else
         {
@@ -182,7 +176,7 @@
     if (NULL == mapDefinition || baseMapLayerGroupName.empty())
     {
         throw new MgNullArgumentException(L"MgServerTileService.GetTile",
-            __LINE__, __WFILE__, NULL, L"", NULL);
+            __LINE__, __WFILE__, NULL, L"MgGetTileWithOutMapSpecified", NULL);
     }
     if (scaleIndex < 0)
     {
@@ -222,7 +216,7 @@
     if (NULL == mapDefinition || baseMapLayerGroupName.empty())
     {
         throw new MgNullArgumentException(L"MgServerTileService.GetTile",
-            __LINE__, __WFILE__, NULL, L"", NULL);
+            __LINE__, __WFILE__, NULL, L"MgGetTileWithOutMapSpecified", NULL);
     }
 
     if (scaleIndex < 0)
@@ -355,15 +349,15 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// Create tilename from mapDefinition, scaleIndex, row, and column USING METATILES
-/// APIVERSION 1.2 use locking method specified in sm_lockMethod
+// Get tile using mapDefinition, scaleIndex, row, and column USING METATILES
+/// APIVERSION 1.2 and using the locking method specified in sm_lockMethod
 MgByteReader* MgServerTileService::GetMetaTile(MgResourceIdentifier* mapDefinition,
                                            CREFSTRING baseMapLayerGroupName,
                                            INT32 tileColumn,
                                            INT32 tileRow,
                                            INT32 scaleIndex)
 {
-    Ptr<MgByteReader> ret;
+    Ptr<MgByteReader> returnedSubtile;
     FILE* lockFile = NULL;
     STRING tilePathname, lockPathname;
     // metatiling vars
@@ -376,11 +370,13 @@
    MG_TRY()
 
     // Generate tile and lock pathnames for later use
-    m_tileCache->GeneratePathnames(mapDefinition, scaleIndex, baseMapLayerGroupName,
-        tileColumn, tileRow, tilePathname, lockPathname, false);
+    //m_tileCache->GeneratePathnames(mapDefinition, scaleIndex, baseMapLayerGroupName,
+    //    tileColumn, tileRow, tilePathname, lockPathname, false);
 
-    //  additional names and control variables for meta tiles
-    // which subTile from sm_useMetaTiles^2 larger tile
+    ////// compute additional names and control variables to deal with meta tiles:
+    // a meta tile is sm_useMetaTiles^2 larger than the requested subtile so there are less tiles computed per map
+    // the metatile coords are computed from original coords modulo metatilesize
+    // e.g. with metatile=2 4 tiles (0,0)(0,1)(1,0)(1,1) get mapped to metatile(0,0)
     subTileX = abs(tileColumn % sm_useMetaTiles);
     subTileY = abs(tileRow % sm_useMetaTiles);
     // determine left top corner of metaTile having sm_useMetaTiles**2 subtiles
@@ -388,7 +384,7 @@
     metaTileRow = tileRow - subTileY;
 
     maxX = maxY = sm_useMetaTiles;  // init control vars
-    // iterate subtiles
+    //// iterate subtiles and create all pathnames of the created tiles
     for (int y=0; y < maxY; y++)    // subtile rows
     for (int x=0; x < maxX; x++)    // subtile columns
     {   // Generate tile and lock pathnames.
@@ -397,55 +393,48 @@
             metaTileColumn + x, metaTileRow + y, subTilePathname[x][y], subTileLockPathname[x][y], false);
     }
 
-    // Generate tile and lock pathnames for meta tile in the mod xx grid
+    // Generate tile and lock pathnames for meta tile in the larger grid mod xx 
     m_tileCache->GeneratePathnames(mapDefinition, scaleIndex, baseMapLayerGroupName,
         metaTileColumn, metaTileRow, metaTilePathname, metaTileLockPathname, false);
 
-    // sm_lockMethod == 1 using 1 remapped metalockfile for all subtiles
-    // sm_lockMethod == 2 using 1 lockfile for each subtiles
-    // sm_lockMethod == 3 using 1 ace condition per metatile
-    switch (sm_lockMethod)
+    // sm_lockMethod == 0 is using 1 remapped metalockfile for all subtiles
+    // sm_lockMethod > 0 is using 1 an ace condition mapped by metatilename
+    if (sm_lockMethod)
     {
-    case 3:    // use ace conditions no files
-        m_tileCache->WaitForLock(metaTilePathname);
-        break;
-    case 2:
-        if (DetectTileLockFile(lockPathname, tilePathname))
-        {
 #ifdef _DEBUG
+        {
             std::wstringstream text;
-            text << L"(" << ACE_OS::thr_self() << L") METATILE: DeletedDanglingLockfile(" << tileRow  
-                << L", " <<  tileColumn << L") " << lockPathname << L")\n" ;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: " << "WaitForLock(" 
+                << tileRow << L", " <<  tileColumn << L") (" << metaTilePathname << L")\n" ;
             ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
+        }
 #endif
-            // TODO: Handle the exception by displaying a tile with an error message?
-            MgFileUtil::DeleteFile(lockPathname, true);
-        }        
-        break;
-    default:
-    case 1: // default
-        if (DetectTileLockFile(metaTileLockPathname, metaTilePathname))
-        {
+        m_tileCache->WaitForLock(metaTilePathname);
+    } 
+    else // this is the same locking strategie as with single tiles but using one mapped metatile locking all subtile requests
+    {
+        bool fileExist = DetectTileLockFile(metaTileLockPathname, metaTilePathname);
+        if (fileExist)
+        {   // TODO: Handle the exception by displaying a tile with an error message?
+            MgFileUtil::DeleteFile(metaTileLockPathname, true);
 #ifdef _DEBUG
             std::wstringstream text;
-            text << L"(" << ACE_OS::thr_self() << L") METATILE: DeletedDanglingLockfile(" << metaTileRow  
-                << L", " <<  metaTileColumn << L") " << metaTileLockPathname << L")\n" ;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: " << (fileExist?L"DeletedDanglingLockfile(":L"NoLockfile(")
+                << metaTileRow << L", " <<  metaTileColumn << L") " << metaTileLockPathname << L")\n" ;
             ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
-            // TODO: Handle the exception by displaying a tile with an error message?
-            MgFileUtil::DeleteFile(metaTileLockPathname, true);
         }     
-    } /// end switch
+    }
     // try getting the tile from the cache first time
-    cacheHit = ret = m_tileCache->Get(tilePathname);
+    cacheHit = returnedSubtile = m_tileCache->Get(tilePathname);
 #ifdef _DEBUG
-        std::wstringstream text;
-        text << L"(" << ACE_OS::thr_self() << (cacheHit?L") CACHEHIT":L") CACHEMISS") << L": GetTile(" 
-            << tileRow  << L", " <<  tileColumn << L") " << tilePathname << L"\n";
-        ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
+    std::wstringstream text;
+    text << L"(" << ACE_OS::thr_self() << (cacheHit?L") CACHEHIT":L") CACHEMISS") << L": GetTile(" 
+        << tileRow  << L", " <<  tileColumn << L") " << tilePathname << L"\n";
+    ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
     // if the reader is NULL then the tile wasn't in the cache and we need to generate it
-    while (NULL == ret) // while is needed to use break; =========================================
+    while (NULL == returnedSubtile) // while for if to be able to use break to skip to end;
     {
         Ptr<MgMap> map;
 
@@ -453,125 +442,78 @@
         // thread safe so we need to deserialize the map within the mutex to ensure
         // that a Rewind() is not called in the middle of a Deserialize().
         // Lockfile test and creation is in same protected scope.
-        { // ------------------------ LLLLOOOOOOCCCCCKKKKKIIIIINNNGGGG
+        { // ------------------------ Locking Context
             // Attempt to get the mapcache mutex .
             ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
-            switch(sm_lockMethod) 
+            if (sm_lockMethod) 
             {
-            case 3:// TODO do we need the second lock test here in a signal/wait algorithm?
-                m_tileCache->LockTile(metaTilePathname);
-                break;
-            case 2: // Bail out if the tile file has been locked for so long.
-                if (DetectTileLockFile(lockPathname, tilePathname))
+            // we DONT need the second lock test here in a signal/wait algorithm
+//          m_tileCache->WaitForLock(metaTilePathname);
+            } 
+            else 
+            {
+                if (DetectTileLockFile(metaTileLockPathname, metaTilePathname)) //
                 {
                     MgStringCollection arguments;
-                    arguments.Add(lockPathname);
-                    throw new MgFileIoException(L"MgServerTileService.GetTile",
-                        __LINE__, __WFILE__, &arguments, L"MgUnableToLockMetaTileFile", NULL);
-                }        
-                break;
-            default:
-            case 1:
-                if (DetectTileLockFile(metaTileLockPathname, metaTilePathname))
-                {
-                    MgStringCollection arguments;
                     arguments.Add(metaTileLockPathname);
                     throw new MgFileIoException(L"MgServerTileService.GetTile",
                         __LINE__, __WFILE__, &arguments, L"MgUnableToLockMetaTileFile", NULL);
-                }        
-            } // end switch  ------------------------ LLLLOOOOOOCCCCCKKKKKIIIIINNNGGGG
+                }
+            }
             
             // try getting the tile from the cache second time ???????????????????????????????????????????
-            cacheHit = ret = m_tileCache->Get(tilePathname);
+            cacheHit = returnedSubtile = m_tileCache->Get(tilePathname);
 
-            if (NULL != ret)
+            if (NULL != returnedSubtile)
             {
 #ifdef _DEBUG
                 std::wstringstream text;
                 text << L"(" << ACE_OS::thr_self() << L") CACHEHIT2: GetTile(" << tileRow  << L", " <<  tileColumn << L") " << tilePathname << L"\n";
                 ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
-#endif
-        /////////////////////////////////// tile was in tileCache .. done.
-                break;  
+#endif        
+                break;  /////////////////////////////////// tile was in tileCache .. done.
             } else {
 #ifdef _DEBUG
                 std::wstringstream text;
                 text << L"(" << ACE_OS::thr_self() << L") CACHEMISS2: GetTile(" << tileRow  << L", " <<  tileColumn << L") " << tilePathname << L"\n";
                 ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
+            }    
+            // Create the directory structure all subtiles!
+            for (int y=0; y < maxY; y++)    // rows  
+            for (int x=0; x < maxX; x++)    // columns
+            {   
+                m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName, 
+                    metaTileColumn + x, metaTileRow + y);
             }
-    
-            // ============================================================================ LOCKING
-            switch(sm_lockMethod) 
+            // ==================================================  LOCKING
+            if (sm_lockMethod) 
             {
-            case 3:
-                // Create the directory structure for each subtile!
-                for (int y=0; y < maxY; y++)    // rows  
-                for (int x=0; x < maxX; x++)    // columns
-                {   
-                    m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName, 
-                        metaTileColumn + x, metaTileRow + y);
-                }
-                m_tileCache->LockTile(metaTilePathname);
-                break;
-            case 2: 
-                for (int y=0; y < maxY; y++)    // rows  
-                for (int x=0; x < maxX; x++)    // columns
-                {   // Create the directory structure for each subtile
-                    m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName, 
-                        metaTileColumn + x, metaTileRow + y);
-                    // Create a lock file per sub tile and close it right away.
-                    subTileLockFile[x][y] = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(subTileLockPathname[x][y]), ACE_TEXT("wb"));
+                m_tileCache->LockTile(metaTilePathname);    // ace lock once per metatile
+            } 
+            else
+            {
+                // Create the lock file 
+                lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(metaTileLockPathname), ACE_TEXT("wb"));
 
-                    if (NULL == subTileLockFile[x][y])
-                    {
-                        MgStringCollection arguments;
-                        arguments.Add(subTilePathname[x][y]);
-
-                        throw new MgFileIoException(L"MgServerTileService.GetTile",
-                            __LINE__, __WFILE__, &arguments, L"MgUnableToCreateLockFile", NULL);
-                    }
-                    else
-                    {
-                        ACE_OS::fclose(subTileLockFile[x][y]);
+                if (NULL == lockFile)
+                {
+                    MgStringCollection arguments;
+                    arguments.Add(metaTileLockPathname);
+                    throw new MgFileIoException(L"MgServerTileService.GetTile",
+                        __LINE__, __WFILE__, &arguments, L"MgUnableToCreateLockFile", NULL);
+                }
+                else
+                {
+                    ACE_OS::fclose(lockFile); // and close it right away.
 #ifdef _DEBUG
-                        std::wstringstream text;
-                        text << L"(" << ACE_OS::thr_self() << L") METATILE: CreatedLockfile(" << metaTileRow + y << L", " <<  metaTileColumn + x << L") " 
-                            << L" S(" << x << L", " << y << L") " << subTileLockPathname[x][y] << L")\n";
-                        ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
+                    std::wstringstream text;
+                    text << L"(" << ACE_OS::thr_self() << L") METATILE: CreatedLockfile(" << metaTileRow << L", " <<  metaTileColumn<< L") " 
+                         << metaTileLockPathname << L")\n";
+                    ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
-                    }
-                } // end meta tiling loop for lockfiles
-                break;
-            default:
-            case 1:
-                {   // Create the directory structure for each subtile
-                    m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName, 
-                        metaTileColumn, metaTileRow);
-                    // per array element Create the lock file and close it right away.
-                    lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(metaTileLockPathname), ACE_TEXT("wb"));
-
-                    if (NULL == lockFile)
-                    {
-                        MgStringCollection arguments;
-                        arguments.Add(metaTileLockPathname);
-
-                        throw new MgFileIoException(L"MgServerTileService.GetTile",
-                            __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
-                    }
-                    else
-                    {
-                        ACE_OS::fclose(lockFile);
-#ifdef _DEBUG
-                        std::wstringstream text;
-                        text << L"(" << ACE_OS::thr_self() << L") METATILE: CreatedLockfile(" << metaTileRow << L", " <<  metaTileColumn<< L") " 
-                             << metaTileLockPathname << L")\n";
-                        ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
-#endif
-                    }
-                } // end meta tiling loop for lockfiles
-
-            } // end switch
+                }
+            }
             //=========================================================================
             GetMapFromDefinition(mapDefinition, scaleIndex, map);
         }   // end of mutex scope
@@ -580,10 +522,10 @@
         STRING metaTileName = L"META" + metaTilePathname;
 #ifdef _DEBUG
             std::wstringstream text;
-            text << L"(" << ACE_OS::thr_self() << L") METATILE: RenderMetaTile(" << metaTileRow << L", " <<   metaTileColumn << L") " << metaTileName << L"\n";
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: RenderMetaTile(" << metaTileRow << L", " <<   metaTileColumn << L") " << metaTileName << " using map 0x" << map << L"\n";
             ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
-        Ptr<MgByteReader> metaTile = GetTile(metaTileName, map, scaleIndex, baseMapLayerGroupName, metaTileColumn, metaTileRow);
+        Ptr<MgByteReader> metaTileBitMap = GetTile(metaTileName, map, scaleIndex, baseMapLayerGroupName, metaTileColumn, metaTileRow);
 
         // Get a ServerSide rendering Service only...
         MgServiceManager* serviceMan = MgServiceManager::GetInstance();
@@ -596,57 +538,48 @@
         for (int y=0; y < maxY; y++)    // rows
         for (int x=0; x < maxX; x++)    // columns
         {
-            // generate the tile
-            Ptr<MgByteReader> img = svcRendering->RenderTileFromMetaTile(map, metaTile, x,y);
+            // callback to the rendering service to collect the subtile from the metatile bitmap
+            Ptr<MgByteReader> img = svcRendering->RenderTileFromMetaTile(map, metaTileBitMap, x,y);
             if ((subTileX == x) && (subTileY == y)) 
-                ret = img;       // keep pointer for requested subtile
+                returnedSubtile = img;       // keep pointer for subtile which has triggered the metatile in the current thread
             assert (x < maxX && y < maxY);
+#ifdef _DEBUG
+            std::wstringstream text;    // streams for more compact debug statements
+            text << L"(" << ACE_OS::thr_self();
+            text << L") RenderTileFromMetaTile dim:" << MgTileParameters::tileWidth << L"x" << MgTileParameters::tileHeight;
+            text << L" format:" << MgTileParameters::tileFormat.c_str()  << L" subTile(" << x << L"," << y;
+            text << L") metaTile(" << metaTileRow  << L"," <<  metaTileColumn << L") " << metaTilePathname.c_str() << L"\n";
+            ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
+#endif
             m_tileCache->Set(img, subTilePathname[x][y]);   // store all subtiles in tile cache
 
+            // rewind the reader since setting the tile advances it to the end
             if (img)
             {
+                img->Rewind();
+            }
 #ifdef _DEBUG
+            {
                 std::wstringstream text;
-                text << L"(" << ACE_OS::thr_self() << L") METATILE: SetTileFromMetaTile(" << tileRow  << L", " <<  tileColumn << L") " << subTilePathname[x][y]
-                                            << L" S(" << x << L", " << y << L")\n";
+                text << L"(" << ACE_OS::thr_self() << L") METATILE: " << (img?L"SetTile":L"NoTileReturned");
+                text << "FromMetaTile(" << tileRow  << L", " <<  tileColumn << L") ";
+                text << subTilePathname[x][y] << L" S(" << x << L", " << y << L")\n";
                 ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
-#endif
             }
-            // rewind the reader since setting the tile advances it to the end
-            if (img)
-            {
-                img->Rewind();
-            }
+#endif
         }
         break;
     }   // end of gettile loop end MgMap scope
 
     MG_CATCH(L"MgServerTileService.GetTile")
 
-    // remove all lockfiles
-    switch(sm_lockMethod) // do the locking now
+    // remove all lockfiles or conditions
+    if (sm_lockMethod)
     {
-    case 3:
         m_tileCache->ClearLock(metaTilePathname);
-        break;
-    case 2:
-        for (int y=0; y < maxY; y++)    // rows  
-        for (int x=0; x < maxX; x++)    // columns
-            if (NULL != subTileLockFile[x][y])
-            {
-                MgFileUtil::DeleteFile(subTileLockPathname[x][y], false);
-                {
-#ifdef _DEBUG
-                    std::wstringstream text;
-                    text << L"(" << ACE_OS::thr_self() << L") METATILE: DeletedLockfile(" << metaTileRow + y  << L", " <<  metaTileColumn + x 
-                        << L") S(" << x << L", " << y << subTileLockPathname[x][y] << L")\n";
-                    ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
-#endif
-                }
-            }
-        break;
-    case 1:
-    default:
+    } 
+    else
+    {
         if (NULL != lockFile)
         {
             MgFileUtil::DeleteFile(metaTileLockPathname, false);
@@ -659,7 +592,7 @@
 #endif
             }
         }
-    } // end switch
+    }
 
     MG_THROW()
 
@@ -668,15 +601,14 @@
 #ifdef _DEBUG
         std::wstringstream text;
         text << L"(" << ACE_OS::thr_self() << L") Rendered: GetTILE(" << tileRow  << L", " <<  tileColumn << L") " 
-            << L" S(" << subTileX << L", " << subTileY << tilePathname << L")\n";
+            << L" S(" << subTileX << L", " << subTileY << L") (" << tilePathname << L")\n";
         ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
     }
 
-    return ret.Detach();
+    return returnedSubtile.Detach();
 }
 
-
 ///////////////////////////////////////////////////////////////////////////////
 // look for the tile in the tilecache first
 MgByteReader* MgServerTileService::GetTile(MgMap* map,
@@ -757,7 +689,7 @@
                 arguments.Add(lockPathname);
 
                 throw new MgFileIoException(L"MgServerTileService.GetTile",
-                    __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
+                    __LINE__, __WFILE__, &arguments, L"MgUnableToCreateLockFile", NULL);
             }
             else
             {
@@ -802,8 +734,9 @@
         // generate the tile
         img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow);
 
-        // cache the tile
-        if (!sm_renderOnly && !sm_useMetaTiles)
+        // cache the tile here ONLY IF WE ARE NOT METATILING !!!!
+        // if we do metatiling this is the large metatile here and we cache the subtiles in GetMetaTile ~line600
+        if (!sm_renderOnly && (sm_useMetaTiles == 0))
         {
             m_tileCache->Set(img, tilePathname);
 
@@ -875,7 +808,7 @@
             arguments.Add(lockPathname);
 
             throw new MgFileIoException(L"MgServerTileService.SetTile",
-                __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
+                __LINE__, __WFILE__, &arguments, L"MgUnableToCreateLockFile", NULL);
         }
         else
         {
@@ -919,7 +852,7 @@
         arguments.Add(mapDefinition->ToString());
 
         throw new MgPermissionDeniedException(
-            funcName, __LINE__, __WFILE__, &arguments, L"", NULL);
+            funcName, __LINE__, __WFILE__, &arguments, L"MgPermissionDeniedForResource", NULL);
     }
     return resourceService.Detach();
 }
@@ -931,7 +864,7 @@
     MG_TRY()
 
     if (NULL == map)
-        throw new MgNullArgumentException(L"MgServerTileService.ClearCache", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgNullArgumentException(L"MgServerTileService.ClearCache", __LINE__, __WFILE__, NULL, L"MgNoMapSpecified", NULL);
 
     Ptr<MgResourceIdentifier> resourceId = map->GetMapDefinition();
     ClearMapCache(resourceId->ToString());

Modified: sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.h
===================================================================
--- sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.h	2011-09-30 07:00:47 UTC (rev 6159)
+++ sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.h	2011-09-30 10:55:36 UTC (rev 6160)
@@ -69,6 +69,7 @@
 
     static INT32 sm_lockMethod;
     static INT32 sm_useMetaTiles;
+    static ACE_Recursive_Thread_Mutex sm_mutex;
 
 private:
 
@@ -104,7 +105,6 @@
 
     static bool sm_initialized;
     static MapCache sm_mapCache;
-    static ACE_Recursive_Thread_Mutex sm_mutex;
     static bool sm_renderOnly;
     static INT32 sm_creationCutoffTime;
     static INT32 sm_pollingInterval;

Modified: sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.vcproj
===================================================================
--- sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.vcproj	2011-09-30 07:00:47 UTC (rev 6159)
+++ sandbox/rfc90.2/MgDev/Server/src/Services/Tile/ServerTileService.vcproj	2011-09-30 10:55:36 UTC (rev 6160)
@@ -202,7 +202,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="2"
-				AdditionalIncludeDirectories="..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc"
+				AdditionalIncludeDirectories="..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\Rendering;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS"
 				ExceptionHandling="2"
 				RuntimeLibrary="2"
@@ -227,7 +227,7 @@
 				GenerateDebugInformation="true"
 				ProgramDatabaseFile="$(OutDir)\MgServerTileService.pdb"
 				SubSystem="2"
-				OptimizeReferences="2"
+				OptimizeReferences="1"
 				EnableCOMDATFolding="2"
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"

Modified: sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.cpp
===================================================================
--- sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.cpp	2011-09-30 07:00:47 UTC (rev 6159)
+++ sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.cpp	2011-09-30 10:55:36 UTC (rev 6160)
@@ -25,7 +25,6 @@
 const STRING COLUMN_PREFIX = L"C";
 
 STRING MgTileCache::sm_path = L"";
-MgServerTileService* MgTileCache::sm_tileService = 0;
 INT32 MgTileCache::sm_tileColumnsPerFolder = 30;
 INT32 MgTileCache::sm_tileRowsPerFolder = 30;
 ACE_Recursive_Thread_Mutex MgTileCache::sm_tileMutex;
@@ -34,7 +33,8 @@
 // default constructor
 MgTileCache::MgTileCache(MgServerTileService* tileService)
 {
-    sm_tileService = tileService;   // keep pointer to parent
+    // !!!! DONT USE ADDREF & Ptr<> here since it leaks cos the Ptr<> destructor never gets called
+    m_tileService = tileService;   // keep pointer to parent for access to settings
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -178,15 +178,15 @@
         ret = byteSource->GetReader();
     } else 
     {
-        //if (sm_tileService->sm_lockMethod==3 && sm_tileService->sm_useMetaTiles)
-        //{   // protect creation of lockmap entry with a guard
-        //    ACE_MT(ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, sm_tileService->sm_mutex, 0));
-        //    // create ace condition for this tile as we are going to make it
-        //    ACE_Condition<ACE_Recursive_Thread_Mutex> *wait = 
-        //        new ACE_Condition<ACE_Recursive_Thread_Mutex>(sm_tileService->sm_mutex);
-        //    // keep lock (ace condition) in map
-        //    GetLockMap()[tilePathname] = wait;  
-        //}
+        if (m_tileService->sm_lockMethod==3 && m_tileService->sm_useMetaTiles)
+        {   // protect creation of lockmap entry with a guard
+            ACE_MT(ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, m_tileService->sm_mutex, 0));
+            // create ace condition for this tile as we are going to make it
+            ACE_Condition<ACE_Recursive_Thread_Mutex> *tileLock = 
+                new ACE_Condition<ACE_Recursive_Thread_Mutex>(m_tileService->sm_mutex);
+            // keep lock (ace condition) in map
+            sm_lockMap[tilePathname] = tileLock;  
+        }
     }
 
     MG_CATCH_AND_RELEASE()
@@ -446,11 +446,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 // wait for a previous ace condition 
 void MgTileCache::WaitForLock(CREFSTRING tilePathname)
-{   // protect test of lockmap entry with a guard
-    ACE_Condition<ACE_Recursive_Thread_Mutex> *wait = 0;
+{
+    // protect test of lockmap entry with a guard
+    ACE_Condition<ACE_Recursive_Thread_Mutex> *tileLock = 0;
     // look for lock and wait if found
     ACE_MT(ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, sm_tileMutex));
-    if (wait = sm_lockMap[tilePathname])
+    if (tileLock = sm_lockMap[tilePathname])
     {   // lock has been found
 #ifdef _DEBUG
         std::wstringstream text;
@@ -459,26 +460,26 @@
         ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
         //                ACE_Time_Value waitTime(METATILEWAIT);
-        if (-1 == wait->wait()) // wait forever
+        int ret = tileLock->wait();    // returns -1 if timed out which is not supposed to happen
+        if (-1 == ret) // so the wait might never come back!!! and the thread gets cleaned out by the service manager
         {
 #ifdef _DEBUG
             std::wstringstream text;
-            text << L"(" << ACE_OS::thr_self() << L") METATILE: WaitForLockTimedOut1(" 
-                << tilePathname << L")\n" ;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: WaitForLockTimedOut1(" << tilePathname << L")\n" ;
             ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
             MgStringCollection arguments;
             arguments.Add(tilePathname);
             throw new MgFileIoException(L"MgServerTileService.GetTile",
                 __LINE__, __WFILE__, &arguments, L"MgWaitForLockTimedOut", NULL);
-        } else {
+        }
 #ifdef _DEBUG
+        {
             std::wstringstream text;
-            text << L"(" << ACE_OS::thr_self() << L") METATILE: WaitForLockCAUGHTSIGNAL1(" 
-                << tilePathname << L")\n" ;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: LockReleased(" << tilePathname << L")\n" ;
             ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
+        }
 #endif
-        }
     }        
 }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -486,9 +487,9 @@
 void MgTileCache::LockTile(CREFSTRING tilePathname)
 {
     // create ace condition for this tile as we are going to make it
-    ACE_Condition<ACE_Recursive_Thread_Mutex> *wait = new ACE_Condition<ACE_Recursive_Thread_Mutex>(sm_tileMutex);
+    ACE_Condition<ACE_Recursive_Thread_Mutex> *tileLock = new ACE_Condition<ACE_Recursive_Thread_Mutex>(sm_tileMutex);
     // keep reference to lock (ace condition) in our map
-    sm_lockMap[tilePathname] = wait;
+    sm_lockMap[tilePathname] = tileLock;
 
 #ifdef _DEBUG
     std::wstringstream text;
@@ -513,8 +514,15 @@
                 << L") returns: " << result << L"\n";
             ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
 #endif
-        }
-        sm_lockMap.erase(tilePathname); // erase: this destroys the ace condition
+            sm_lockMap.erase(tilePathname); // erase only existing lock: this destroys the ace condition
+        }else
+        {
+#ifdef _DEBUG
+            std::wstringstream text;
+            text << L"(" << ACE_OS::thr_self() << L") METATILE: NoLockFor(" << tilePathname << L")\n";
+            ACE_DEBUG ((LM_DEBUG, text.str().c_str()));
+#endif
+        }        
     } 
     catch (MgException* e) 
     {

Modified: sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.h
===================================================================
--- sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.h	2011-09-30 07:00:47 UTC (rev 6159)
+++ sandbox/rfc90.2/MgDev/Server/src/Services/Tile/TileCache.h	2011-09-30 10:55:36 UTC (rev 6160)
@@ -85,7 +85,7 @@
     // use a memory based locking scheme
     static std::map<STRING,ACE_Condition<ACE_Recursive_Thread_Mutex>*> sm_lockMap;
 
-    static MgServerTileService* sm_tileService; // pointer to owner
+    MgServerTileService* m_tileService; // pointer to owner
 
 };
 



More information about the mapguide-commits mailing list