SRL Archive - FAQ

Sima opening file unshared mode - bug?


djborec

2012-10-13 06:30:43

Hello,

I use opening file in unshared mode to synchronise more then one account logging out to lobby, because you can not have more then one account in rs lobby (even if you have random.dat read only)

However sometimes for unknown reason file stays open in SIMBA, even when I stop all scripts and run again ,it still gives me exception in all scripts and file can not be open. Thats more likely bug releatd to SIMBA

riwu

2012-10-13 06:37:46

Are you using the file command OpenFile/AppendFile/RewriteFile? You should CloseFile after using them or they won't be freed. (much like how you will free DTM/Bitmaps)

masterBB

2012-10-13 06:48:14

in your init
AddOnTerminate(@CloseMyFiles);

in your script
procedure CloseMyFiles();
begin
CloseFile(MyFile);
end;

if you are not using SRL
SetScriptProp(SP_OnTerminate, [@CloseMyFiles]);

djborec

2012-10-13 06:53:19

OpenFile
function OpenFile(const Path: string; Shared: Boolean): Integer;

Opens file for reading. Opens shared if Shared is true. Returns -1 on failure, otherwise returns the handle to the file.

I am using this function.

Yes I have close file in script . And as I said even If I stop all scripts (which should also close or free file) and restart them again , I am still getting this error.

It has nothing to do with file itself ,because as I said it works for random time and after 1-2-3 hours all scripts get stuck .

And to explain how my script works.

So if I run more then one instance of SIMBA and this script, lets say I run 5.
This script includes hopping worlds. However as I said you can not have more the one account in Lobby (so if there is one and other one tries to leave to lobby ,it will be logged out by rs) . So the script has something like this:

function ableToLogOut:boolean;
begin
fileNR:=OpenFile('C:\file.txt',false);
if not(fileNR=-1) then Result:=true;
end;

then somewhere in oter function which is for logging out and switching world I have this :


if not(ableToLogOut) then
begin
MarkTime(NATL);
repeat
progress('Not able to log out for '+MsToTime(TimeFromMark(NATL), Time_Bare));
waitR(350,450);
until ableToLogOut;
end;

and also if sucessfully changed world ,then there is CloseFile(fileNR); so other script can open it and sucessfully log out.

EDIT:

Ok I will try to add this ,thanks

AddOnTerminate('CloseMyFiles');

masterBB

2012-10-13 07:00:13

I am not sure if it will work, just a guess. I haven't really worked with files that much, if it still doesn't work I will try it too.

riwu

2012-10-13 07:06:55

You called OpenFile in a loop without freeing it which will result in a memory leak (and hence it works for few hours until it crashes).
AddOnterminate will not help in this case since it only frees at script termination, add CloseFile() to your ableToLogOut function.

I don't understand how does opening files help in RS multiple logging though? Use for communication between the scripts?

djborec

2012-10-13 07:10:40

From: riwu
You called OpenFile in a loop without freeing it which will result in a memory leak (and hence it works for few hours until it crashes).
AddOnterminate will not help in this case since it only frees at script termination, add CloseFile() to your ableToLogOut function.

I don't understand how does opening files help in RS multiple logging though? Use for communication between the scripts?


Yes for comunication between scripts, to synchronise logging out ,so no more then one account will be logged out to Lobby or in Lobby.

I thought if I use OpenFile ,but file wont be open ,because its open in other script ,there will be no memory leak ? But it seems like there will be so
Should I add something like:

function ableToLogOut:boolean;
begin
fileNR:=OpenFile('C:\file.txt',false);
if not(fileNR=-1) then
begin
Result:=true;
end else
begin
CloseFile(fileNR);
end;
end;

EDIT:
I rewrite ableToLogOut to form higher ,but I am getting exception invalid fileNum so I guess its not working like that

riwu

2012-10-13 07:24:31

Which part of your script calls CloseFile originally? If CloseFile isn't called, once you call OpenFile('C:\file.txt',false), ableToLogOut will return false forever. (hence all scripts will be stuck in your infinite loop)

It may not be a good idea to communicate by intentionally causing an error though. Why don't write to the file, then other scripts can read it, and also modify accordingly? Allows more flexibility and clearer logic.

djborec

2012-10-20 07:30:35

Why don't write to the file, then other scripts can read it, and also modify accordingly? Allows more flexibility and clearer logic.

But what would I write there? What do you mean? That still need to be opened somehow and readed, so what if 2 simbas write there at a same time, then there will be problem because both will try to log out.

And yes after lot of testing I came to conclusion that its SIMBA's bug, because when I manually stop (I have added on terminate to close file) and then restart scripts ,SIMBA will be not able to open file ,even if its not linked with any SIMBA's. And when I manually try to delete file , windows says that its opened in SIMBA..

riwu

2012-10-20 07:39:48

From: djborec
But what would I write there? What do you mean? That still need to be opened somehow and readed, so what if 2 simbas write there at a same time.

And yes after lot of testing I came to conclusion that its SIMBA's bug, because when I manually stop (I have added on terminate to close file) and then restart scripts ,SIMBA will be notable to open file ,even if its not linked with any SIMBA's

I'm not 100% sure what you want but you can just write any note to inform other script of anything? Like just write '1' to it if it's logged out, then other scripts that reads the file and retrieve 1 will be able to respond and probably clears the file for further rewriting. You have to work out the logic correctly. Openfile should probably have sharing to true, but to prevent 2 simba writing at same time you can set share to false while rewriting/appending the file.


From: djborec
And when I manually try to delete file , windows says that its opened in SIMBA..

Again, likely because you didn't close them properly within the script.

djborec

2012-10-20 17:15:58

From: riwu

Again, likely because you didn't close them properly within the script.


I have AddOnTerminate('CloseMyFiles'); and method closemyfiles has closefile in it. So even if I stop all scripts ,then it should close file in script where it is open ,so when I restart them one of scripts should be able to open file. But no all scripts running after restart are not able to open it. :/

I bet I will have to rewrite it ,but can possibly happen same with your thing that writting 1 in file, but again when its unshared ,there comes this problem when any of scripts can open it

Brandon

2012-10-27 01:08:02

Do the following.. Copy the two scripts into two different Simba Tabs. One per Tab.
Run the first one.

Then attempt to run the second one. Note that both scripts are now running at the same time but the first one has locked the file and the second one prints errors constantly.

Finally, press ALT on the keyboard and the first script will close the file.. Tab 2 will now open that same file successfully and continuously read it just like Tab 1.

Press the Escape key and both scripts will stop attempting to read the file.

This example is only here to prove that you can synchronize communication via a FileLock/Mutex mechanism like you attempted. Don't forget to change the location of the file you're reading for both scripts as the script is trying to read a file on MY computer. Make it read one on yours.

Tab 1:

{$I SRL/SRL.Simba}

var
Text: String;
Handle: LongInt;



Procedure OpenFileUnShared(var Handle: LongInt; FilePath: String);
Begin
Handle := OpenFile(FilePath, False);
If (Handle <> - 1) Then
Writeln('Tab 1 File Successfully Opened.');
End;

Procedure CloseFileHandle;
Begin
CloseFile(Handle);
Writeln('Tab 1 File Successfully Closed.');
End;


begin
//AddOnTerminate('CloseFileHandle');
ClearDebug;
OpenFileUnShared(Handle, 'C:\Simba\Includes\SRL\SRL.Simba');
While(Not IsKeyDown(VK_MENU)) Do
Begin
Text := '';
If (Not ReadFileString(Handle, Text, FileSize(Handle))) Then
WriteLn('Error Reading File');
SetFileCharPointer(Handle, 0, 0);
Sleep(50);
End;
CloseFileHandle;
While (Not IsKeyDown(VK_ESCAPE)) Do
Wait(50);
end.



Tab 2:

{$I SRL/SRL.Simba}

var
Text: String;
Handle: LongInt;



Procedure OpenFileShared(var Handle: LongInt; FilePath: String);
Begin
If (Handle = -1) Then
Handle := OpenFile(FilePath, False)
Else
writeln('Tab 2 File Opened Successfully.');
End;

Procedure CloseFileHandle;
Begin
CloseFile(Handle);
Writeln('Tab 2 File Successfully Closed');
End;


begin
Handle := -1;
AddOnTerminate('CloseFileHandle');

While(Not IsKeyDown(VK_ESCAPE)) Do
Begin
Try
OpenFileShared(Handle, 'C:\Simba\Includes\SRL\SRL.Simba');
Text := '';
If (Not ReadFileString(Handle, Text, FileSize(Handle))) Then
WriteLn('Error Reading File');
SetFileCharPointer(Handle, 0, 0);
Sleep(50);
If (Handle <> -1) Then
Exit;
Except
End;
End;
end.