+ if (is_frozen) {
+ switch (ps->frozen) {
+ case FREEZING:
+ case FROZEN:
+ return; /* nothing to do */
+
+ case THAWING:
+ /*
+ * We were in the middle of emptying our bufchain, and got
+ * frozen again. In that case, winhandl.c is already
+ * throttled, so just return to FROZEN state. The toplevel
+ * callback will notice and disable itself.
+ */
+ ps->frozen = FROZEN;
+ break;
+
+ case UNFROZEN:
+ /*
+ * The normal case. Go to FREEZING, and expect one more
+ * load of data from winhandl if we're unlucky.
+ */
+ ps->frozen = FREEZING;
+ break;
+ }
+ } else {
+ switch (ps->frozen) {
+ case UNFROZEN:
+ case THAWING:
+ return; /* nothing to do */
+
+ case FREEZING:
+ /*
+ * If winhandl didn't send us any data throughout the time
+ * we were frozen, then we'll still be in this state and
+ * can just unfreeze in the trivial way.
+ */
+ assert(bufchain_size(&ps->inputdata) == 0);
+ ps->frozen = UNFROZEN;
+ break;
+
+ case FROZEN:
+ /*
+ * If we have buffered data, go to THAWING and start
+ * releasing it in top-level callbacks.
+ */
+ ps->frozen = THAWING;
+ queue_toplevel_callback(handle_socket_unfreeze, ps);
+ }
+ }