Hello,
I wanted to know how something works: Both solutions for Tuos_Player.FreePlayer (); they make sure that the thread is Free (Given the presence of "FreeOnTerminate: = True;") If you are using Tuos_Player.FreePlayer (); separately before uos_Free (): uosPlayers [] is updated to nil? (I tested it and it seems to me no) Because the uos_Free call () for x: = 0 to length (uosPlayers) -1 do begin if assigned (uosPlayers [x]) then <WARNING> begin uosPlayers [x] .FreePlayer; end; It risks a problem I saw Tuos_Player.onTerminate (); but it does not run! procedure Tuos_Player.onTerminate() ; begin if ifflat = true then begin uosPlayers[Index].destroy; uosPlayersStat[Index] := -1 ; end else destroy; end; and it is not correct (the free thread is automatic) http://lazarus-ccr.sourceforge.net/docs/rtl/classes/tthread.doterminate.html or http://lazarus-ccr.sourceforge.net/docs/rtl/classes/tthread.onterminate.html procedure Tuos_Player.; begin uosPlayers[Index]:= nil; uosPlayersStat[Index] := -1 ; end; |
Administrator
|
Hello.
Thanks to note it. Indeed, few time ago (because of LCL that does not free everything if FreeOnTerminate: = false, even after player.free), I added FreeOnTerminate: = true (and that way, all is freed in LCL too). Write you later. Fre;D |
Hello,
sorry if I add other things but I think they should be seen together.. I made a remark perhaps interesting. In "uos_Free ()" method there is "Sleep (50)". If I use "uos_Free ()" instead of "freeplayer" the value 50 is not enough and then crash (not for a real problem), but if I put for example Sleep(1000) then it works (for my computer). Probably even my crash and caused a few problems in the timings (Play (), Stop () solution). I think there are values of sleep that some computers are not for others. I think it would be useful to have a method that makes the sleep function but also that controls the actual execution. while ..control.. do Sleep(10); for example: (tested with the changes introduced in previous post) function ThereArePlayersNotFree: Boolean; Var i: Integer; begin if uosPlayers <> nil then for i:= 0 to Length(uosPlayers)-1 do if uosPlayersStat[i] <> -1 then begin Result:= True; Exit; end; Result:= False; end; procedure uos_Free(); ... //sleep(50); old code while ThereArePlayersNotFree do Sleep(10); ... end; so in theory make code more robust (it does not think the appropriate value sleep). This should also be applied to other situations for the use of Sleep. PS. I do not currently know if it also requires the use of a TCriticalSection. I just made a simple test with a single player and it works. But the basic idea I think would be interesting to apply. Note: I believe that the following line will be adjusted: if uosPlayers[PlayerIndex] <> nil then uosPlayers[PlayerIndex].Terminate; (procedure uos_CreatePlayer(PlayerIndex : cint32);) with the execute() current has no effect |
Administrator
|
This post was updated on .
Hello.
Ok, change commited in 8d9c856..65065e9, I hope it is better now.: Procedure uos_FreePlayer(PlayerIndex: cint32) ; // Works only when PlayNoFree() was used: free the player begin if (length(uosPlayers) > 0) and (PlayerIndex +1 <= length(uosPlayers)) then if uosPlayersStat[PlayerIndex] = 1 then begin uosPlayers[PlayerIndex].FreePlayer() ; uosPlayers[PlayerIndex] := nil; end end; PS: I did not study yet your last topic, maybe the new release solve the problems. Fre;D |
Administrator
|
This post was updated on .
Re-hello.
Ooops, Player.OnTerminate() ---> was not used ---> old code from 5 years ago ;-( Removed in last commit 65065e9..ffeee3b. I will study your last topic asap. Fre;D |
Administrator
|
Re-re-hello.
Re-added with correct parameter Player.OnTerminate(sender: Tobject). ---> (sender: Tobject) was missing in old releases --> added: procedure Tuos_Player.OnTerminate(sender : Tobject); begin inherited OnTerminate(sender); if ifflat = true then begin uosPlayers[Index] := nil; uosPlayersStat[Index] := -1 ; end; end; Fre;D |
Hello,
there is a programming problem procedure OnTerminate(sender: Tobject); procedure Tuos_Player.OnTerminate(sender : Tobject); begin inherited OnTerminate(sender);//??? if ifflat = true then begin uosPlayers[Index] := nil; uosPlayersStat[Index] := -1 ; end; end; WHERE IS USED IT? NOT WORK! (If you want to check, for example, you write an empty file with OnTerminate: you will see that is not called) you can use: virtual method of TThread procedure DoTerminate; override; or assign event for TThread OnTerminate:= OnTerminateEvent; To my problem see previous post about "Sleep (50)" PS. for the alternative solution post "Mar 17, 2017; 7:39pm" What do you think? |
Administrator
|
Hello.
OK, I have added your proposition, many thanks : Commit 69416bb..acf9b78 function PlayersNotFree: Boolean; Var i: Integer; begin if uosPlayers <> nil then for i:= 0 to Length(uosPlayers)-1 do if uosPlayers[i] <> nil then begin Result:= True; Exit; end; Result:= False; end; procedure uos_Free(); var x : integer; begin if assigned(uosPlayers) then if length(uosPlayers) > 0 then for x := 0 to length(uosPlayers) -1 do begin if assigned(uosPlayers[x]) then begin uos_FreePlayer(x); end; end; while PlayersNotFree do Sleep(10); uos.uos_free(); end; procedure uos_unloadlib() ; var x: cint32; begin if assigned(uosPlayers) then begin if (length(uosPlayers) > 0) then for x := 0 to high(uosPlayers) do if uosPlayersStat[x] = 1 then begin if uosPlayers[x].Status > 0 then begin uosPlayers[x].nofree := false; uosPlayers[x].Stop(); while PlayersNotFree do Sleep(10); end; end; setlength(uosPlayers, 0) ; setlength(uosPlayersStat, 0) ; end; uos.uos_unloadlib() ; end; PS: All sleep are using your method in uos_flat.pas For uos.pas, the conditions are different, each case must have his own sleep-method. It is on the todo list. Many thanks. ----------------------------- From your last topic: > WHERE IS USED IT? NOT WORK! Hah, strange, here it works, did you try last commit ? > for the alternative solution post "Mar 17, 2017; 7:39pm" What do you think? Is not what I did in last commits ? Fre;D |
Administrator
|
This post was updated on .
In reply to this post by Phoenix
Hello.
> NOT WORK! OK, I am lost. I ask help in fpc forum. http://free-pascal-general.1045716.n5.nabble.com/TThread-OnTerminate-td5727888.html#a5727910 Fre;D |
Hello,
Thank you for your changes, then I write to you for a few details.. > OK, I am loosed. > I ask help in fpc forum. Because? if you've chosen to use the virtual method CERTAIN THAT DOES NOT WORK procedure OnTerminate(sender: Tobject); override; it may be that you have not seen the "DOterminate" in my post: "DO..." not "ON..." for solve procedure DOTerminate; override; |
Administrator
|
Hello.
OK, finally, I get it. Added Tuos_Player.DoTerminate in last commit acf9b78..69db11a. Many thanks for help Phoenix. PS: Do you have still problems with last release ? Fre;D |
Administrator
|
Re-hello.
Hum, I realize that maybe in Tuos_Player.DoTerminate; ---> inherited DoTerminate; is not needed. Fre;D |
Hello,
Thank you for your changes. > inherited DoTerminate; in this case I think if leave it or remove it does not change > Do you have still problems with last release ? Yes, DoTerminate work but I have a crash because there is one detail There is an issue to use properly PlayersNotFree (). In my solution use: "If uosPlayersStat [i] <> -1 then" sorry for (error in my post) "if uosPlayers <> nil then for i:= 0 to Length(uosPlayers)-1 do" function PlayersNotFree: Boolean; Var i: Integer; begin if uosPlayersStat <> nil then for i:= 0 to Length(uosPlayersStat)-1 do if uosPlayersStat[i] <> -1 then begin Result:= True; Exit; end; Result:= False; end; But even this (yours) can work: "If uosPlayers [i] <> nil then" the problem is in: Procedure uos_FreePlayer(PlayerIndex: cint32) ; begin ............ uosPlayers[PlayerIndex].FreePlayer() ; uosPlayers[PlayerIndex] := nil; <<< THIS uosPlayersStat[PlayerIndex] := -1; <<< THIS end end; these lines are to be performed in DoTerminate (after the actual execution of freeplayer ()) or the "while" blocks at the first sleep (10) if you want to leave at least "uosPlayers [PlayerIndex]: = nil;" you have to use PlayersNotFree () with "uosPlayersStat" NOTE: consider that you may run into an infinite loop potential if for example a thread does not end. This is easily avoidable but bypassing the "while", if a thread is not terminated, however you would get an access to invalid memory or a visible crash (my case). > For uos.pas, the conditions are different, each case must have his own sleep-method. It is on the todo list I am glad that you have found interesting the idea. The solution should be used where it is really needed in order to avoid infinite loops (on the thread are also more dangerous). So you have to be very careful. Where it is needed more attention you can put in check some sort of time limit (certainly avoid the infinite loop). Only for example nt:= 300; //= 3 second (big enough to cover every possibility of the case) while ..control.. and (nt <> 0) do begin Sleep(10); Dec(nt); end; sorry for my English (with all these posts there will be a lot of mistakes) Thanks |
Hello,
sorry I just posted (watch it) but there is a consideration uosPlayers [PlayerIndex]: = nil; need in uos_FreePlayer () because need in uos_Free() then you can only use "uosPlayersStat" solution for PlayersNotFree() and remove only "uosPlayersStat[PlayerIndex] := -1;" from uos_FreePlayer() (read the previous post) |
Administrator
|
Hello Phoenix.
Thanks for your light. It is very useful because ... with my computer (netbook Lenovo) I do not have any crash. Is this code OK ? : function PlayersNotFree: Boolean; Var i: Integer; begin if uosPlayersStat <> nil then for i:= 0 to Length(uosPlayersStat)-1 do if uosPlayersStat[i] <> -1 then begin Result:= True; Exit; end; Result:= False; end; Procedure uos_FreePlayer(PlayerIndex: cint32) ; begin if (length(uosPlayers) > 0) and (PlayerIndex +1 <= length(uosPlayers)) then if uosPlayersStat[PlayerIndex] = 1 then begin uosPlayers[PlayerIndex].FreePlayer() ; uosPlayers[PlayerIndex] := nil; end; end; procedure uos_Free(); var x : integer; nt : integer = 300; begin if assigned(uosPlayers) then if length(uosPlayers) > 0 then for x := 0 to length(uosPlayers) -1 do begin if assigned(uosPlayers[x]) then begin uos_FreePlayer(x); end; end; while (PlayersNotFree = true) and (nt > 0) do begin Sleep(10); Dec(nt); end; uos.uos_free(); end; Fre;D |
Administrator
|
Re-hello.
Change from previous post are in last commit 69db11a..5fc2425. I hope this one is the good one ;-) (If no, no problem, we will win at the end). Fre;D |
Hello,
I tested with several combinations is that everything seems to work perfect !! PS. the only thing in common with the two computers I used for the test are the number of cores, and Windows: 1) intel four cores (more than 5 years of age) Win Vista 32bit 2) intel four cores (8 threads) Win 10 64bit On the second computer with linux, no crash with (Sleep(50)) Thanks!! |
Administrator
|
Yep, many thanks for your help.
Fred. |
Free forum by Nabble | Edit this page |