Strategies for event-driven concurrency

Is there any good formal investigation or at least definition of different strategies of event-driven concurrent programming?

I’ve read that there exist readiness based (pull based) and completion based (push based) approaches, and also callback based and polling based ones. I believe the two classifications are orthogonal:

               | readiness based | completion based | ---------------|-----------------|------------------| callback based |                 |                  | ---------------|-----------------|------------------| polling based  |                 |                  | ---------------|-----------------|------------------| 

Additionally, callback based and polling based are not mutually exclusive: a callback can be used for notification that polling can be retried.

What i’ve read so far gives me only some vague intuition, and distinctions are fuzzy. For example, for an I/O operation to be ready, i suppose that some other operation needs to be completed, and once some operation is completed, something else can become ready.

So, are there any good academic-level references on this subject?