event

package module
v0.0.0-...-bfc44bb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2014 License: MIT Imports: 1 Imported by: 0

README

event

go get bitbucket.org/zobar/event

Package event provides a minimal select/poll/epoll/kqueue-based event loop for Go applications that require evented IO notifications. This is particularly useful for code that interfaces with asynchronous C libraries, which often assume an event loop is available.

This is an interface-only package, and has no dependencies of its own. Subpackage libevent provides a simple implementation which depends on the libevent C library.

There are a handful of other C libraries which also provide event loops, such as libev, libuv, CoreFoundation's CFRunLoop, glib's GMainLoop, and Qt's QSocketNotifier. If you implement one of these backends, I strongly encourage you to make a pull request.

Please see GoDoc for full documentation.

Documentation

Overview

Package event provides a minimal select/poll/epoll/kqueue-based event loop for Go applications that require evented IO notifications. This is particularly useful for code that interfaces with asynchronous C libraries, which often assume an event loop is available.

This is an interface-only package, and has no dependencies of its own. Subpackage libevent provides a simple implementation which depends on the libevent C library (http://libevent.org).

There are a handful of other C libraries which also provide event loops, such as libev (http://software.schmorp.de/pkg/libev.html), libuv (https://github.com/joyent/libuv), CoreFoundation's CFRunLoop (https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFRunLoopRef/Reference/reference.html), glib's GMainLoop (https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html), and Qt's QSocketNotifier (http://qt-project.org/doc/qt-5.0/qtcore/qsocketnotifier.html). If you implement one of these backends, I strongly encourage you to make a pull request.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FD

type FD uintptr

FD represents an OS file descriptor.

type IOFlags

type IOFlags int16

IOFlags are used to describe file statuses. They may be bitwise-ORed if more than one status applies.

const (
	// Read indicates that a file or socket is readable.
	Read IOFlags = 1 << iota

	// Write indicates that a file or socket is writable.
	Write
)

type IOSource

type IOSource Source

An IOSource monitors an open file or socket's readable and/or writable status. IOSources are "level-triggered," meaning they will fire each time through the event loop for as long as the condition holds. (It also means that an infinite loop is likely to result if your event handler does not either change the file's state or remove itself from the loop.)

Example
package main

import (
	"bitbucket.org/zobar/event"
	"bitbucket.org/zobar/event/libevent"
	"fmt"
	"os"
	"syscall"
	"time"
)

func main() {
	wait := make(chan bool)

	// Get a reference to the shared libevent event loop.
	loop := libevent.MainLoop()

	hi := loop.IOSource(event.FD(syscall.Stdin), event.Read, func(event.IOSource, event.IOFlags) {
		// At this point, we have to read the bytes out of the file descriptor.
		// Otherwise the file descriptor will remain readable, and we will
		// continue to get notified.
		buf := make([]byte, 256)
		os.Stdin.Read(buf)

		fmt.Println("Hello, world!")
	})

	// Events need to be explicitly added, or else they won't fire.
	hi.Add()

	// IOSources have no intrinsic timeout. If a timeout is desired, you must
	// create a separate TimerSource.
	bye := loop.TimerSource(2*time.Second, func(event.TimerSource) {
		fmt.Println("Goodbye.")
		close(wait)
	})
	bye.Add()

	fmt.Println("Press enter quickly for a friendly message.")
	<-wait

	// Not normally necessary, but we need to clean up for the other examples.
	hi.Remove()
	bye.Remove()

}
Output:

Press enter quickly for a friendly message.
Goodbye.

type Loop

type Loop interface {

	// IOSource() creates a new IOSource for monitoring an open file's readable
	// and/or writable status. The event source is not active until Add() is
	// called on it.
	IOSource(fd FD, flags IOFlags, callback func(source IOSource, flags IOFlags)) IOSource

	// TimerSource() creates a new TimerSource for emitting events repeatedly
	// after a given timeout. The event source is not active until Add() is
	// called on it.
	TimerSource(timeout time.Duration, callback func(source TimerSource)) TimerSource
}

Loop manages a set of IOSources and TimerSources. This is the main entry point to the event package. How you obtain a Loop depends on what type of code you're writing:

If you are writing a library, your best bet is to accept a Loop as a parameter to your top-level constructor. This will make your library more flexible, since it insulates your code from the implementation decisions of your users.

If you are writing an application, subpackage libevent makes a simple, shared event loop available through libevent.MainLoop(). Other implementations based on different libraries may eventually become available.

type Source

type Source interface {

	// Add makes an event source active. Once an event source is active, it will
	// emit events until it is explicitly removed.
	Add() error

	// Remove is called to deactivate an event source. After an event source is
	// deactivated, it will no longer emit events. An event source can be added
	// again after it's been removed.
	Remove() error
}

Source is a common interface implemented by all event sources.

type TimerSource

type TimerSource Source

TimerSource is an event source which emits events repeatedly after a given timeout.

Example
package main

import (
	"bitbucket.org/zobar/event"
	"bitbucket.org/zobar/event/libevent"
	"fmt"
	"time"
)

func main() {
	wait := make(chan bool)

	// Get a reference to the shared libevent event loop.
	loop := libevent.MainLoop()

	// Events repeat until they are removed.
	tick := loop.TimerSource(500*time.Millisecond, func(event.TimerSource) {
		fmt.Printf("tick... ")
	})

	// Events need to be explicitly added, or else they won't fire.
	tick.Add()

	boom := loop.TimerSource(2*time.Second, func(event.TimerSource) {
		fmt.Printf("BOOM!\n")
		close(wait)
	})
	boom.Add()

	<-wait

	// Not normally necessary, but we need to clean up for the other examples.
	tick.Remove()
	boom.Remove()

}
Output:

tick... tick... tick... tick... BOOM!

Directories

Path Synopsis
Package libevent provides a simple event loop based on the libevent C library (http://libevent.org).
Package libevent provides a simple event loop based on the libevent C library (http://libevent.org).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL