Tom Moers wrote:
> | thread1 | thread2 |
> | start | |
> | ..work.. | |
> | grab (iteration 1) | | <-- new connection is created
> | ..work.. | start |
> | release | ..work.. |
> | ..work.. | grab (iteration 1) | <-- connection is reused
> but switched threads!
> | grab (iteration 2) | ..work.. | <-- new connection is created
> | | |
> Maybe I'm missing something, but I think the above is not
> unlikely to happen.
So...you're contending that a modern computer can't start 14 threads in
less time than it takes to make an IPC connection and transfer some data
Once again, I'm not saying that your scenario cannot happen. I brought
this very thing up in my previous email, so I'm not sure why you went to
the trouble to diagram it. What I'm saying is that it should only
happen if the machine takes a context switch away from creating threads
that lasts long enough for at least one of the threads that is created
to finish. Seems unlikely to me. I'd think we would have seen crashes
during testing if it ever actually happened...which it had plenty of
opportunity to do during development because of test/cpool.cpp.
> I don't understand how you can call connection->thread_start() on
> entry of the worker_thread because you only have the connection
> instance after calling grab()?
Sorry, I thought it was a static method. It arguably should be, since
it doesn't actually use the MYSQL object held by the DBDriver.
You still don't want to call it inside the thread, so you'd have to
rearrange the code so the first grab() is outside the loop, too. You'd
call thread_start() on the returned connection, then enter the loop.
> >> and thread_end before calling poolptr->release())?
> > No, the other way around: call thread_end() after the release(),
> > outside the for loop, just before the thread returns.
> Similar as above. If you release the connection, how can you
> call one of its methods?
Leaving the static method issue aside, you may still be able to call
thread_end() on the Connection after releasing it. The only risk is if
there's a usage pattern where the connection is immediately destroyed on
release(). Otherwise, it's safe to call thread_end() through a pointer
someone else nominally owns because it doesn't actually change the state
of the Connection object.
Yes, it's dodgy.