> On Sun, September 24, 2006 22:19, Bart Samwel wrote:
>
>> It looks like connection_base::RemoveTrigger() is failing. I guess we
>> have R.second = R.first = m_Triggers.end(), in which case this line:
>>
>> const TriggerList::iterator i = find(R.first, R.second, E);
>>
>> may fail in some implementations, but definitely this one:
>>
>>        if (m_Conn && (R.second == ++R.first))
>>          Exec(("UNLISTEN \"" + T->name() + "\"").c_str(), 0);
>>
>> Jeroen? Any idea if this can ever happen?
>
> Good work...  I'm not sure though: why should that find() fail if R.first
> and R.second are both equal to m_Triggers.end()?  AFAICS find(x, x, y) is
> a find() on an empty range, and so should always return x without it ever
> being dereferenced or incremented.  Shouldn't behaviour be perfectly
> well-defined even if x is an end()?

I ran the test in the visual studio debugger and find() goes past without 
problem.  Of course in the test R.first is not end() so it's not a test if 
find() will fail when both argument is end(), although I'm inclined to agree 
with the accessment above.


> So Zhao (or Xiaofeng, which should I use?), could you test this fix for
> src/connection_base.cxx, lines 591-597?

Xiaofeng will do.

>
> {
>   // Erase first; otherwise a notification for the same trigger may yet 
> come
>   // in and wreak havoc.  Thanks Dragan Milenkovic.
> +  const bool gone = (m_Conn && (R.second == ++R.first));
>   m_Triggers.erase(i);
>
> -  if (m_Conn && (R.second == ++R.first))
> +  if (gone)
>     Exec(("UNLISTEN \"" + T->name() + "\"").c_str(), 0);
> }
>
> All that that does is move the computation of the "if" condition up before
> the erase().  If our analysis is correct, that should fix the problem.
>

Bravo, That fixed it!

Xiaofeng 

_______________________________________________
Libpqxx-general mailing list
[email protected]
http://gborg.postgresql.org/mailman/listinfo/libpqxx-general

Reply via email to