You are not logged in.
Pages: 1
In 31-WebSockets\Project31ChatServer.dpr, I try to use TSynObjectListLocked in TChatService to save the IChatCallback because I like to control the lock myself and will access certain global variables in the service in the future. But during the debugging process, I found that an AV error was generated when calling callback in TchatService.BlaBla. To be precise, it was an exception generated in FPC_INTF_ASSIGN.
The strange thing is that when I retain the original array of IChatCallback and register it with the Client, and also retain the InterfaceArrayAdd(f2,callback);, the program will not generate an AV exception. I really didn't understand the reason.
Here is the gist: https://gist.github.com/zen010101/87a35 … c211996889
Offline
If the program has InterfaceArrayAdd(), then
intf := fConnected[i]
will not report an error;
If you comment it out, an error will be reported.
Your explanation seems to be the exact opposite of what I stated.
Offline
TSynObjectListLocked is for TObject not interface.
As its name states.
Thank you for your reminder. By searching the source code, I feel that the TSynLogCallbacks object in mormot.core.log.pas is what I am looking for. I can refer to it to implement my own Callback Interface List.
However, I still feel strange, why does a certain statement in the following code "magically" avoid the AV exception ?
procedure TChatService.Join(const pseudo: string;
const callback: IChatCallback);
begin
if fConnected = nil then
fConnected := TSynObjectListLocked.Create(false);
fConnected.Add(callback);
InterfaceArrayAdd(f2,callback); // This statement magically avoids the AV exception generated by the `Intf := fConnected[i]` statement in the BlaBla Method below.
end;
Offline
In fact, TSynObjectListLocked assign pointers, whereas InterfaceArrayAdd() assign interface, i.e. not only copy the pointer but call IInterface._Acquire which increment the instance refcount within the f2 list.
So there is no dangling pointer any more.
Note that with heavily multi threaded process, i.e. a lot of concurrent Join() then InterfaceArrayAdd() would start randomly trigger GPF because its internal f2 storage is not protected by a lock.
Offline
Note that with heavily multi threaded process, i.e. a lot of concurrent Join() then InterfaceArrayAdd() would start randomly trigger GPF because its internal f2 storage is not protected by a lock.
Even if optExecLockedPerInterface option is used when creating IChatService ?
Server.ServiceDefine(TChatService,[IChatService],sicShared).
SetOptions([],[optExecLockedPerInterface]). // thread-safe fConnected[]
ByPassAuthentication := true;
Offline
Pages: 1