Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
IW 15.1.x+ gSessions.Execute Q&A
#1
Finally upgrading to 15.1.2, I've got some questions (based on some assumptions) about dealing with session lists.

One thing I do occasionally is rip through the sessions to gather status information, including some app specific data from UserSession.

Questions regarding gSessions.Execute(): 
1.  Is it safe to read data from UserSession?  (form xx:=TIWUserSession(LSession.Data).MyValue)
2.  Is it safe to write data to UserSession?  (form TIWUserSession(LSession.Data).MyFlag:=true)
3.  Do I need to lock the session, or does the gSessions.Execute() lock before calling the procedure?

I do know that this kind of procedure works (see snip below), just converting from the SessionList demo, but:

Code:
gSessions.Execute(LSessionList[i],
        procedure(aSession: TObject)
        var
          LSession: TIWApplication absolute aSession;
        begin
          LSession.Lock;

          try
            xx:=TIWUserSession(LSession.Data).MyValue;
             // etc
          finally
            LSession.Unlock;    
          end;
        end;);

Is this kind of cross session (UserSession access) safe?
Is the session.lock redundant? 

I finally got back to work on some IW stuff so am upgrading, but my source access isn't turned on yet so I don't know what's behind the .execute curtain.

Thanks,

Dan
Reply
#2
Hi Dan, I'm glad that I can answer it for a change :-)

I think they all can be answered at once:

- the Execute() method runs inside a lock (a high level lock applied at the collection - gSessions - level, not a session lock), so the UserSession is guaranteed to exist during the whole method. No other code will, for instance, just destroy that session and leave you with an access violation.

However, that lock is shared, not exclusive. This is good because even if your session is locked by some other code, you can still read it status (things that don't change or things that are safe to access even by multiple threads, e.g. the session ID). On the other hand, you are not free to do whatever you want with it, because other code might be using it at the same time.

So, bottom line is: treat it as any other object that needs to be read/written by multiple threads. Some properties are safe like LastAccess (which uses Interlocked* functions to handle it internally). Other boolean and 32bit numeric values might also be safe to read/write from multiple threads because they usually work atomically. But if you have objects or strings, then that's a different story. You need to use some form of protection there.

You have 2 options: Explicitly lock the session before reading/writing to it (which will lock the whole thing and might fail if the session is already locked) or you can implement a more granular lock (you can create a critical section for each session and lock it only when reading/writing certain properties). If what you intend to do runs very quickly, maybe you can start with the session lock and see if it works well. You can locking/unlocking as session is really *fast*. The only "if" there happens when the session is already locked. But you can try to lock it using a very low timeout value, so the code won't wait if the session is already locked.
Please let me know if you need some example
Reply
#3
Thanks!

What I'm doing is a quick snapshot of session details, so for myself I think your answer is enough. If I hit a locked session I can loop back to it at some point, nothing I'm doing with this is critical at this point. I do have some strings I'm reading, but most are unlikely to change. Doubles (TTimes in particular) for session start and last access time will be changing. Stuff like that.

Almost all is reading, though I have a "traceon" flag that I might write. It's boolean.

But, others might want to be more adventurous. An example, or doc page, might be a good thing to put on the "to do" list for some time in the future. It's unlikely I'm the only one that will want to do this stuff. Don't put aside development for it on account of me though.

Oops... one more question springs from this: If I use a session lock, and my lock is successful, will it break other session activity or will that activity wait for my unlock?

Dan
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)