After looking at the lock handling that is used for user and owner objects (and possible other daemon resources as well) I've seen that the DropUser() calls appear everywhere cluttering up the code and are easy to forget when coding.

I think it would be preferable to use guard classes. (I don't know if this is the correct term but it's what they're called at work for our mutex handling.)

Instead calling FetchUser() and getting a pointer back which must returned via DropUser() a guard object is created which holds the pointer and the guard destructor automatically calls DropUser() when the guard goes out of scope.

Example old code:

ICQUser *u = gUserManager.FetchUser(szId, nPPID, LOCK_R);
int messages = u->NewMessages();
gUserManager.DropUser(u);


Example of new code:

// If the current scope is too long, add braces to limit the scope
{
  // Create a guard object, the constructor will call
  //   gUserManager.FetchUser() and store the returned ICQUser pointer
  //   internally in the guard.
  IcqUserGuard u(szId, nPPID, LOCK_R);

  // No difference here. Operator -> is overloaded to make the guard
  //   transparent.
  int messages = u->NewMessages();

// When the Guard goes out of scope, the destructor is called which will
//   do a DropUser() on the ICQUser.
}



The guard destructor will always be called. No need to call DropUser() before returns, breaks or in else-blocks. Also exceptions can be thrown anywhere.

It should be simple to implement as the guard will require very little code to work. New code can use the guard while existing code will be unaffected and can be kept as is until someone takes to time to do the search and replace.


I'm not sure if this is something to add to the current daemon or if it should be part of the new API only, but my vote is on the current code as it is not much work but makes lock handling so much easier.

/Anders

Reply via email to