To keep our code at Google in the best possible shape we provided our software engineers with these constant reminders. Now, we are happy to share them with the world.
Many thanks to these folks for inspiration and hours of hard work getting this guide done:
Flaw #1: Constructor does Real Work
Warning Signs
Flaw #2: Digging into Collaborators
Flaw #3: Brittle Global State & Singletons
Flaw #4: Class Does Too Much
4 int bottles_of_beer = 0; 5 void Intern1() { bottles_of_beer++; } // Intern1 forgot to use Mutex. 6 void Intern2() { bottles_of_beer++; } // Intern2 copied from Intern1. 7 int main() { 8 // Folks, bring me one bottle of beer each, please. 9 ClosureThread intern1(NewPermanentCallback(Intern1)),10 intern2(NewPermanentCallback(Intern2));11 intern1.SetJoinable(true); intern2.SetJoinable(true);12 intern1.Start(); intern2.Start();13 intern1.Join(); intern2.Join();14 CHECK_EQ(2, bottles_of_beer) << "Who didn't bring me my beer!?";15 }
$ helgrind path/to/your/programPossible data race during read of size 4 at 0x5429C8 at 0x400523: Intern2() tott.cc:6 by 0x400913: _FunctionResultCallback_0_0::Run() ... by 0x4026BB: ClosureThread::Run() ... ... Location 0x5429C8 has never been protected by any lock Location 0x5429C8 is 0 bytes inside global var "bottles_of_beer" declared at tott.cc:4