[Solved] Directory loop without global?

Just starting out? Need help? Post your questions and find answers here.
BarryG
Addict
Addict
Posts: 4118
Joined: Thu Apr 18, 2019 8:17 am

[Solved] Directory loop without global?

Post by BarryG »

Anyone know how I can convert this code to NOT use a global variable to hold the directory size? Because my app needs to call this routine multiple times now from different threads, and the var is getting incorrectly updated even though my app is thread-safe. :(

Source -> https://www.purebasic.fr/english/viewto ... 82#p171382

Code: Select all

Global foldersize.q ; Don't want to rely on this being global.

Procedure.q FolderSizeRoutine(dir$)
  dir=ExamineDirectory(#PB_Any,dir$,"")
  If dir
    While NextDirectoryEntry(dir)
      If DirectoryEntryType(dir)=#PB_DirectoryEntry_File
        foldersize+DirectoryEntrySize(dir)
        Continue
      ElseIf Not DirectoryEntryName(dir)="." And Not DirectoryEntryName(dir)=".."
        FolderSizeRoutine(dir$+DirectoryEntryName(dir)+"\")
        Continue
      EndIf
    Wend
    FinishDirectory(dir)
  EndIf
  ProcedureReturn foldersize
EndProcedure

Procedure.q FolderSize(dir$)
  If Right(dir$,1)<>"\"
    dir$+"\"
  EndIf
  foldersize=0
  FolderSizeRoutine(dir$)
  ProcedureReturn foldersize
EndProcedure

Debug FolderSize("C:\Windows\System32\") ; Example of current non-thread use.
Last edited by BarryG on Sun Jun 09, 2024 8:27 am, edited 1 time in total.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Directory loop without global?

Post by jassing »

Or keep it simple... (now with thread demo) (assuming you don't need the size in one location, just from individual threads)

Code: Select all

EnableExplicit

Procedure.q FolderSize(dir$)
  Protected size.q, dir
  dir=ExamineDirectory(#PB_Any,dir$,"")
  
  If dir
    While NextDirectoryEntry(dir)
      If DirectoryEntryType(dir)=#PB_DirectoryEntry_File
        size+DirectoryEntrySize(dir)
      ElseIf Not DirectoryEntryName(dir)="." And Not DirectoryEntryName(dir)=".."
        size+FolderSize(dir$+"\"+DirectoryEntryName(dir)+"\")
      EndIf
    Wend
    FinishDirectory(dir)
  Else
    size=-1
  EndIf
  ProcedureReturn size
EndProcedure

Procedure threadTest( *folder )
  Debug FormatNumber(FolderSize(PeekS(*folder)),0) + " bytes in "+PeekS(*folder)
EndProcedure  

Define h1=CreateThread(@threadTest(),@"c:\windows\system32"),
       h2=CreateThread(@threadTest(),@"C:\temp"),
       h3=CreateThread(@threadTest(),@"c:\non-existant\folder")

Debug FormatNumber(FolderSize(#PB_Compiler_Home),0) +" bytes in "+#PB_Compiler_Home
WaitThread(h1) : WaitThread(h2) : WaitThread(h3)
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Directory loop without global?

Post by idle »

that's better :D
BarryG
Addict
Addict
Posts: 4118
Joined: Thu Apr 18, 2019 8:17 am

Re: Directory loop without global?

Post by BarryG »

Thanks, but the size for "System32" isn't correct (it's 21 bytes off). The code in my first post gets the correct size.

Image

Image

[Edit] Doing only ONE thread makes it work:

Code: Select all

EnableExplicit

Procedure.q FolderSize(dir$)
  Protected size.q, dir
  dir=ExamineDirectory(#PB_Any,dir$,"")
  If dir
    While NextDirectoryEntry(dir)
      If DirectoryEntryType(dir)=#PB_DirectoryEntry_File
        size+DirectoryEntrySize(dir)
      ElseIf Not DirectoryEntryName(dir)="." And Not DirectoryEntryName(dir)=".."
        size+FolderSize(dir$+"\"+DirectoryEntryName(dir)+"\")
      EndIf
    Wend
    FinishDirectory(dir)
  EndIf
  ProcedureReturn size
EndProcedure

Procedure threadTest( *folder )
  Debug FormatNumber(FolderSize(PeekS(*folder)),0) + " bytes in "+PeekS(*folder)
EndProcedure  

Define h1=CreateThread(@threadTest(),@"c:\windows\system32")
WaitThread(h1)
Last edited by BarryG on Sun Jun 09, 2024 8:29 am, edited 3 times in total.
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: Directory loop without global?

Post by DarkDragon »

Probably because If dir fails (permissions?) and size = -1 leads to a subtraction of one.
bye,
Daniel
BarryG
Addict
Addict
Posts: 4118
Joined: Thu Apr 18, 2019 8:17 am

Re: [Solved] Directory loop without global?

Post by BarryG »

Edited my post above because it's working if I create one thread. Don't know why.
AZJIO
Addict
Addict
Posts: 2141
Joined: Sun May 14, 2017 1:48 am

Re: [Solved] Directory loop without global?

Post by AZJIO »

The hard drive will still be a bottleneck
Post Reply