Change Suppressor from channel-based to mutex-based, add tests.

The reasoning behind this change is the incredible overhead of the
previous reactor request/response model:

Overhead for previous model for every user-facing method:

- 2 struct type definitions (req/resp)
- 1 channel
  - 1 struct member definition site
  - 1 channel init site
  - 1 struct population site
  - 1 struct servicing site
  - 1 struct closing site
- 1 actual execution method

New lock-based code:

Per object: 1 lock
Per method:
- 1 taking the lock
- 1 actual execution method

This starts with the simplest possible locking scheme: lock the object-global
mutex at the beginning of each user-facing method. This is equivalent to
implicit locking provided by the reactor.

If this goes well, we can convert the other reactors later.