Added download slots and automatic download cancellation after a delay
This commit is contained in:
56
PBMap.pb
56
PBMap.pb
@@ -125,6 +125,7 @@ Module PBMap
|
|||||||
CacheFile.s
|
CacheFile.s
|
||||||
GetImageThread.i
|
GetImageThread.i
|
||||||
Download.i
|
Download.i
|
||||||
|
Time.i
|
||||||
EndStructure
|
EndStructure
|
||||||
|
|
||||||
Structure BoundingBox
|
Structure BoundingBox
|
||||||
@@ -198,6 +199,7 @@ Module PBMap
|
|||||||
TimerInterval.i
|
TimerInterval.i
|
||||||
MaxMemCache.i ; in MiB
|
MaxMemCache.i ; in MiB
|
||||||
MaxThreads.i ; Maximum simultaneous web loading threads
|
MaxThreads.i ; Maximum simultaneous web loading threads
|
||||||
|
MaxDownloadSlots.i ; Maximum simultaneous download slots
|
||||||
TileLifetime.i
|
TileLifetime.i
|
||||||
Verbose.i ; Maximum debug informations
|
Verbose.i ; Maximum debug informations
|
||||||
Warning.i ; Warning requesters
|
Warning.i ; Warning requesters
|
||||||
@@ -288,7 +290,10 @@ Module PBMap
|
|||||||
Redraw.i
|
Redraw.i
|
||||||
Dragging.i
|
Dragging.i
|
||||||
Dirty.i ; To signal that drawing need a refresh
|
Dirty.i ; To signal that drawing need a refresh
|
||||||
|
|
||||||
MemoryCacheManagement.i ; To pause web loading threads
|
MemoryCacheManagement.i ; To pause web loading threads
|
||||||
|
DownloadSlots.i ; Actual nb of used download slots
|
||||||
|
DownloadSlotsMutex.i ; To be sure that only one thread at a time can access to the DownloadSlots var
|
||||||
|
|
||||||
List TracksList.Tracks() ; To display a GPX track
|
List TracksList.Tracks() ; To display a GPX track
|
||||||
List Markers.Marker() ; To diplay marker
|
List Markers.Marker() ; To diplay marker
|
||||||
@@ -687,6 +692,8 @@ Module PBMap
|
|||||||
PBMap\Options\MaxMemCache = Val(Value)
|
PBMap\Options\MaxMemCache = Val(Value)
|
||||||
Case "maxthreads"
|
Case "maxthreads"
|
||||||
PBMap\Options\MaxThreads = Val(Value)
|
PBMap\Options\MaxThreads = Val(Value)
|
||||||
|
Case "maxdownloadslots"
|
||||||
|
PBMap\Options\MaxDownloadSlots = Val(Value)
|
||||||
Case "tilelifetime"
|
Case "tilelifetime"
|
||||||
PBMap\Options\TileLifetime = Val(Value)
|
PBMap\Options\TileLifetime = Val(Value)
|
||||||
Case "verbose"
|
Case "verbose"
|
||||||
@@ -756,6 +763,8 @@ Module PBMap
|
|||||||
ProcedureReturn StrU(\MaxMemCache)
|
ProcedureReturn StrU(\MaxMemCache)
|
||||||
Case "maxthreads"
|
Case "maxthreads"
|
||||||
ProcedureReturn StrU(\MaxThreads)
|
ProcedureReturn StrU(\MaxThreads)
|
||||||
|
Case "maxdownloadslots"
|
||||||
|
ProcedureReturn StrU(\MaxDownloadSlots)
|
||||||
Case "tilelifetime"
|
Case "tilelifetime"
|
||||||
ProcedureReturn StrU(\TileLifetime)
|
ProcedureReturn StrU(\TileLifetime)
|
||||||
Case "verbose"
|
Case "verbose"
|
||||||
@@ -818,6 +827,7 @@ Module PBMap
|
|||||||
WritePreferenceInteger("WheelMouseRelative", \WheelMouseRelative)
|
WritePreferenceInteger("WheelMouseRelative", \WheelMouseRelative)
|
||||||
WritePreferenceInteger("MaxMemCache", \MaxMemCache)
|
WritePreferenceInteger("MaxMemCache", \MaxMemCache)
|
||||||
WritePreferenceInteger("MaxThreads", \MaxThreads)
|
WritePreferenceInteger("MaxThreads", \MaxThreads)
|
||||||
|
WritePreferenceInteger("MaxDownloadSlots", \MaxDownloadSlots)
|
||||||
WritePreferenceInteger("TileLifetime", \TileLifetime)
|
WritePreferenceInteger("TileLifetime", \TileLifetime)
|
||||||
WritePreferenceInteger("Verbose", \Verbose)
|
WritePreferenceInteger("Verbose", \Verbose)
|
||||||
WritePreferenceInteger("Warning", \Warning)
|
WritePreferenceInteger("Warning", \Warning)
|
||||||
@@ -882,7 +892,8 @@ Module PBMap
|
|||||||
PreferenceGroup("OPTIONS")
|
PreferenceGroup("OPTIONS")
|
||||||
\WheelMouseRelative = ReadPreferenceInteger("WheelMouseRelative", #True)
|
\WheelMouseRelative = ReadPreferenceInteger("WheelMouseRelative", #True)
|
||||||
\MaxMemCache = ReadPreferenceInteger("MaxMemCache", 20480) ; 20 MiB, about 80 tiles in memory
|
\MaxMemCache = ReadPreferenceInteger("MaxMemCache", 20480) ; 20 MiB, about 80 tiles in memory
|
||||||
\MaxThreads = ReadPreferenceInteger("MaxThreads", 10)
|
\MaxThreads = ReadPreferenceInteger("MaxThreads", 40)
|
||||||
|
\MaxDownloadSlots = ReadPreferenceInteger("MaxDownloadSlots", 2)
|
||||||
\TileLifetime = ReadPreferenceInteger("TileLifetime", 1209600) ; about 2 weeks ;-1 = unlimited
|
\TileLifetime = ReadPreferenceInteger("TileLifetime", 1209600) ; about 2 weeks ;-1 = unlimited
|
||||||
\Verbose = ReadPreferenceInteger("Verbose", #False)
|
\Verbose = ReadPreferenceInteger("Verbose", #False)
|
||||||
\Warning = ReadPreferenceInteger("Warning", #False)
|
\Warning = ReadPreferenceInteger("Warning", #False)
|
||||||
@@ -1031,6 +1042,8 @@ Module PBMap
|
|||||||
ProcedureReturn PBMap\Layers(Name)\Alpha
|
ProcedureReturn PBMap\Layers(Name)\Alpha
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
|
;-***
|
||||||
|
|
||||||
Procedure MemoryCacheManagement()
|
Procedure MemoryCacheManagement()
|
||||||
; If cache size exceeds limit, try to delete the oldest tiles used (first in the time stack)
|
; If cache size exceeds limit, try to delete the oldest tiles used (first in the time stack)
|
||||||
Protected CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 5 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
Protected CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 5 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
||||||
@@ -1133,6 +1146,20 @@ Module PBMap
|
|||||||
|
|
||||||
Procedure GetImageThread(*Tile.Tile)
|
Procedure GetImageThread(*Tile.Tile)
|
||||||
MyDebug("Thread starting for image " + *Tile\CacheFile + "(" + *Tile\key + ")", 5)
|
MyDebug("Thread starting for image " + *Tile\CacheFile + "(" + *Tile\key + ")", 5)
|
||||||
|
; Waits for a free download slot
|
||||||
|
LockMutex(PBMap\DownloadSlotsMutex)
|
||||||
|
While PBMap\DownloadSlots >= PBMap\Options\MaxDownloadSlots
|
||||||
|
UnlockMutex(PBMap\DownloadSlotsMutex)
|
||||||
|
If ElapsedMilliseconds() - *Tile\Time > 10000
|
||||||
|
MyDebug(" Thread for image " + *Tile\CacheFile + " canceled after 10 seconds waiting for a slot.", 5)
|
||||||
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
||||||
|
ProcedureReturn #False
|
||||||
|
EndIf
|
||||||
|
Delay(500)
|
||||||
|
LockMutex(PBMap\DownloadSlotsMutex)
|
||||||
|
Wend
|
||||||
|
PBMap\DownloadSlots + 1
|
||||||
|
UnlockMutex(PBMap\DownloadSlotsMutex)
|
||||||
*Tile\Download = ReceiveHTTPFile(*Tile\URL, *Tile\CacheFile, #PB_HTTP_Asynchronous)
|
*Tile\Download = ReceiveHTTPFile(*Tile\URL, *Tile\CacheFile, #PB_HTTP_Asynchronous)
|
||||||
If *Tile\Download
|
If *Tile\Download
|
||||||
Repeat
|
Repeat
|
||||||
@@ -1143,22 +1170,23 @@ Module PBMap
|
|||||||
Size = FinishHTTP(*Tile\Download)
|
Size = FinishHTTP(*Tile\Download)
|
||||||
MyDebug(" Thread for image " + *Tile\CacheFile + " finished. Size : " + Str(Size), 5)
|
MyDebug(" Thread for image " + *Tile\CacheFile + " finished. Size : " + Str(Size), 5)
|
||||||
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
||||||
*Tile\Download = 0
|
|
||||||
ProcedureReturn #True
|
ProcedureReturn #True
|
||||||
Case #PB_Http_Failed
|
Case #PB_Http_Failed
|
||||||
FinishHTTP(*Tile\Download)
|
FinishHTTP(*Tile\Download)
|
||||||
MyDebug(" Thread for image " + *Tile\CacheFile + " failed.", 5)
|
MyDebug(" Thread for image " + *Tile\CacheFile + " failed.", 5)
|
||||||
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
||||||
*Tile\Download = 0
|
|
||||||
ProcedureReturn #False
|
ProcedureReturn #False
|
||||||
Case #PB_Http_Aborted
|
Case #PB_Http_Aborted
|
||||||
FinishHTTP(*Tile\Download)
|
FinishHTTP(*Tile\Download)
|
||||||
MyDebug(" Thread for image " + *Tile\CacheFile + " aborted.", 5)
|
MyDebug(" Thread for image " + *Tile\CacheFile + " aborted.", 5)
|
||||||
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
||||||
*Tile\Download = 0
|
|
||||||
ProcedureReturn #False
|
ProcedureReturn #False
|
||||||
Default
|
Default
|
||||||
MyDebug(" Thread for image " + *Tile\CacheFile + " downloading " + Str(Progress) + " bytes", 5)
|
MyDebug(" Thread for image " + *Tile\CacheFile + " downloading " + Str(Progress) + " bytes", 5)
|
||||||
|
If ElapsedMilliseconds() - *Tile\Time > 60000
|
||||||
|
MyDebug(" Thread for image " + *Tile\CacheFile + " canceled after 60 seconds.", 5)
|
||||||
|
AbortHTTP(*Tile\Download)
|
||||||
|
EndIf
|
||||||
EndSelect
|
EndSelect
|
||||||
EndIf
|
EndIf
|
||||||
Delay(500) ; Frees CPU
|
Delay(500) ; Frees CPU
|
||||||
@@ -1227,6 +1255,7 @@ Module PBMap
|
|||||||
\URL = URL
|
\URL = URL
|
||||||
\CacheFile = CacheFile
|
\CacheFile = CacheFile
|
||||||
\nImage = 0
|
\nImage = 0
|
||||||
|
\Time = ElapsedMilliseconds()
|
||||||
\GetImageThread = CreateThread(@GetImageThread(), *NewTile)
|
\GetImageThread = CreateThread(@GetImageThread(), *NewTile)
|
||||||
If \GetImageThread
|
If \GetImageThread
|
||||||
MyDebug(" Creating get image thread nb " + Str(\GetImageThread) + " to get " + CacheFile, 3)
|
MyDebug(" Creating get image thread nb " + Str(\GetImageThread) + " to get " + CacheFile, 3)
|
||||||
@@ -2281,7 +2310,7 @@ Module PBMap
|
|||||||
Case #PB_EventType_LeftButtonDown
|
Case #PB_EventType_LeftButtonDown
|
||||||
; LatLon2Pixel(@PBMap\GeographicCoordinates, @PBMap\PixelCoordinates, PBMap\Zoom)
|
; LatLon2Pixel(@PBMap\GeographicCoordinates, @PBMap\PixelCoordinates, PBMap\Zoom)
|
||||||
PBMap\Dragging = #True
|
PBMap\Dragging = #True
|
||||||
;Mem cursor Coord
|
; Memorize cursor Coord
|
||||||
PBMap\MoveStartingPoint\x = CanvasMouseX
|
PBMap\MoveStartingPoint\x = CanvasMouseX
|
||||||
PBMap\MoveStartingPoint\y = CanvasMouseY
|
PBMap\MoveStartingPoint\y = CanvasMouseY
|
||||||
; Clip MouseX to the map range (in X, the map is infinite)
|
; Clip MouseX to the map range (in X, the map is infinite)
|
||||||
@@ -2408,7 +2437,11 @@ Module PBMap
|
|||||||
*Tile = EventData()
|
*Tile = EventData()
|
||||||
key = *Tile\key
|
key = *Tile\key
|
||||||
; After a Web tile loading thread, clean the tile structure memory and set the image nb in the cache
|
; After a Web tile loading thread, clean the tile structure memory and set the image nb in the cache
|
||||||
; avoid to have threads accessing vars (and avoid mutex), see GetImageThread()
|
; avoid to have threads accessing vars (and avoid some mutex), see GetImageThread()
|
||||||
|
*Tile\Download = 0
|
||||||
|
LockMutex(PBMap\DownloadSlotsMutex)
|
||||||
|
PBMap\DownloadSlots - 1
|
||||||
|
UnlockMutex(PBMap\DownloadSlotsMutex)
|
||||||
Protected timg = PBMap\MemCache\Images(key)\Tile\nImage ; Get this new tile image nb
|
Protected timg = PBMap\MemCache\Images(key)\Tile\nImage ; Get this new tile image nb
|
||||||
PBMap\MemCache\Images(key)\nImage = timg ; Stores it in the cache using the key
|
PBMap\MemCache\Images(key)\nImage = timg ; Stores it in the cache using the key
|
||||||
FreeMemory(PBMap\MemCache\Images(key)\Tile) ; Frees the data needed for the thread
|
FreeMemory(PBMap\MemCache\Images(key)\Tile) ; Frees the data needed for the thread
|
||||||
@@ -2421,7 +2454,7 @@ Module PBMap
|
|||||||
; Redraws at regular intervals
|
; Redraws at regular intervals
|
||||||
Procedure TimerEvents()
|
Procedure TimerEvents()
|
||||||
If EventTimer() = PBMap\Timer And (PBMap\Redraw Or PBMap\Dirty)
|
If EventTimer() = PBMap\Timer And (PBMap\Redraw Or PBMap\Dirty)
|
||||||
MemoryCacheManagement()
|
; MemoryCacheManagement()
|
||||||
Drawing()
|
Drawing()
|
||||||
EndIf
|
EndIf
|
||||||
EndProcedure
|
EndProcedure
|
||||||
@@ -2484,6 +2517,11 @@ Module PBMap
|
|||||||
PBMap\Window = Window
|
PBMap\Window = Window
|
||||||
PBMap\Timer = 1
|
PBMap\Timer = 1
|
||||||
PBMap\Mode = #MODE_DEFAULT
|
PBMap\Mode = #MODE_DEFAULT
|
||||||
|
PBMap\DownloadSlotsMutex = CreateMutex()
|
||||||
|
If PBMap\DownloadSlotsMutex = #False
|
||||||
|
MyDebug("Cannot create a mutex", 0)
|
||||||
|
End
|
||||||
|
EndIf
|
||||||
LoadOptions()
|
LoadOptions()
|
||||||
TechnicalImagesCreation()
|
TechnicalImagesCreation()
|
||||||
SetLocation(0, 0)
|
SetLocation(0, 0)
|
||||||
@@ -2799,8 +2837,8 @@ CompilerIf #PB_Compiler_IsMainFile
|
|||||||
CompilerEndIf
|
CompilerEndIf
|
||||||
|
|
||||||
; IDE Options = PureBasic 5.60 (Windows - x64)
|
; IDE Options = PureBasic 5.60 (Windows - x64)
|
||||||
; CursorPosition = 893
|
; CursorPosition = 1162
|
||||||
; FirstLine = 894
|
; FirstLine = 1143
|
||||||
; Folding = -------------------
|
; Folding = -------------------
|
||||||
; EnableThread
|
; EnableThread
|
||||||
; EnableXP
|
; EnableXP
|
||||||
|
Reference in New Issue
Block a user