Skip to content

Instantly share code, notes, and snippets.

@nicolai86
Created December 15, 2017 05:50
Show Gist options
  • Save nicolai86/fd720c9a660188fe29d7ac7a810f96f3 to your computer and use it in GitHub Desktop.
Save nicolai86/fd720c9a660188fe29d7ac7a810f96f3 to your computer and use it in GitHub Desktop.
osx sleep/ wake notifications in golang
package main
import (
"C"
"log"
"time"
)
//export CanSleep
func CanSleep() C.int {
time.Sleep(5 * time.Second)
return 1
}
//export WillWake
func WillWake() {
time.Sleep(5 * time.Second)
log.Printf("Will Wake")
}
//export WillSleep
func WillSleep() {
time.Sleep(5 * time.Second)
log.Printf("Will Sleep")
}
package main
// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit
// int CanSleep();
// void WillWake();
// void WillSleep();
// #include "main.h"
import "C"
import (
"log"
"time"
)
func main() {
go func() {
C.registerNotifications()
log.Printf("Go bye")
}()
log.Printf("Hello, World")
time.Sleep(time.Minute)
C.unregisterNotifications()
time.Sleep(time.Minute)
}
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <mach/mach_port.h>
#include <mach/mach_interface.h>
#include <mach/mach_init.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
io_connect_t root_port; // a reference to the Root Power Domain IOService
// notification port allocated by IORegisterForSystemPower
IONotificationPortRef notifyPortRef;
// notifier object, used to deregister later
io_object_t notifierObject;
// this parameter is passed to the callback
void *refCon;
CFRunLoopRef runLoop;
void MySleepCallBack(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
{
printf("messageType %08lx, arg %08lx\n",
(long unsigned int)messageType,
(long unsigned int)messageArgument);
switch (messageType)
{
case kIOMessageCanSystemSleep:
if (CanSleep())
{
IOAllowPowerChange(root_port, (long)messageArgument);
}
else
{
IOCancelPowerChange(root_port, (long)messageArgument);
}
break;
case kIOMessageSystemWillSleep:
WillSleep();
IOAllowPowerChange(root_port, (long)messageArgument);
break;
case kIOMessageSystemWillPowerOn:
WillWake();
break;
case kIOMessageSystemHasPoweredOn:
break;
default:
break;
}
}
void registerNotifications()
{
root_port = IORegisterForSystemPower(refCon, &notifyPortRef, MySleepCallBack, &notifierObject);
if (root_port == 0)
{
printf("IORegisterForSystemPower failed\n");
}
CFRunLoopAddSource(CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes);
runLoop = CFRunLoopGetCurrent();
CFRunLoopRun();
}
void unregisterNotifications()
{
CFRunLoopRemoveSource(runLoop,
IONotificationPortGetRunLoopSource(notifyPortRef),
kCFRunLoopCommonModes);
IODeregisterForSystemPower(&notifierObject);
IOServiceClose(root_port);
IONotificationPortDestroy(notifyPortRef);
CFRunLoopStop(runLoop);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment