apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
{
struct apm_user *as = filp->private_data;
- unsigned long flags;
int err = -EINVAL;
if (!as->suser || !as->writer)
* Wait for the suspend/resume to complete. If there
* are pending acknowledges, we wait here for them.
*/
- flags = current->flags;
+ freezer_do_not_count();
wait_event(apm_suspend_waitqueue,
as->suspend_state == SUSPEND_DONE);
+
+ /*
+ * Since we are waiting until the suspend is done, the
+ * try_to_freeze() in freezer_count() will not trigger
+ */
+ freezer_count();
} else {
as->suspend_state = SUSPEND_WAIT;
mutex_unlock(&state_lock);
* Wait for the suspend/resume to complete. If there
* are pending acknowledges, we wait here for them.
*/
- flags = current->flags;
-
- wait_event_interruptible(apm_suspend_waitqueue,
+ wait_event_freezable(apm_suspend_waitqueue,
as->suspend_state == SUSPEND_DONE);
}
- current->flags = flags;
-
mutex_lock(&state_lock);
err = as->suspend_result;
as->suspend_state = SUSPEND_NONE;
#define FREEZER_H_INCLUDED
#include <linux/sched.h>
+#include <linux/wait.h>
#ifdef CONFIG_PM_SLEEP
/*
current->flags &= ~PF_NOFREEZE;
}
+/*
+ * Freezer-friendly wrapper around wait_event_interruptible(), originally
+ * defined in <linux/wait.h>
+ */
+
+#define wait_event_freezable(wq, condition) \
+({ \
+ int __retval; \
+ do { \
+ __retval = wait_event_interruptible(wq, \
+ (condition) || freezing(current)); \
+ if (__retval && !freezing(current)) \
+ break; \
+ else if (!(condition)) \
+ __retval = -ERESTARTSYS; \
+ } while (try_to_freeze()); \
+ __retval; \
+})
#else /* !CONFIG_PM_SLEEP */
static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
static inline void set_freezable(void) {}
+
+#define wait_event_freezable(wq, condition) \
+ wait_event_interruptible(wq, condition)
+
#endif /* !CONFIG_PM_SLEEP */
#endif /* FREEZER_H_INCLUDED */