Cache line most commonly is in states "dirty", "invalid" and "valid" or "shared". On read miss request for read is broadcasted on a bus. All cache controllers are monitoring the bus. The one having the copy in the state "dirty" changes it state to "valid" and send the copy to requesting node. On write miss invalidation of all copies is additionally performed. When writing block in state valid it's state is changed into dirty and broadcast causes all cache controllers invalidate their copies.
Since snooping does not scale well, larger ccNuma systems tend to use Directory-based coherence protocols.