package tao import ( "context" "errors" "fmt" "hash/fnv" "os" "reflect" "runtime" "time" "unsafe" ) // ErrUndefined for undefined message type. type ErrUndefined int32 func (e ErrUndefined) Error() string { return fmt.Sprintf("undefined message type %d", e) } // Error codes returned by failures dealing with server or connection. var ( ErrParameter = errors.New("parameter error") ErrNilKey = errors.New("nil key") ErrNilValue = errors.New("nil value") ErrWouldBlock = errors.New("would block") ErrNotHashable = errors.New("not hashable") ErrNilData = errors.New("nil data") ErrBadData = errors.New("more than 8M data") ErrNotRegistered = errors.New("handler not registered") ErrServerClosed = errors.New("server has been closed") ) // definitions about some constants. const ( MaxConnections = 1000 BufferSize128 = 128 BufferSize256 = 256 BufferSize512 = 512 BufferSize1024 = 1024 defaultWorkersNum = 20 ) type onConnectFunc func(WriteCloser) bool type onMessageFunc func(Message, WriteCloser) type onCloseFunc func(WriteCloser) type onErrorFunc func(WriteCloser) type workerFunc func() type onScheduleFunc func(time.Time, WriteCloser) // OnTimeOut represents a timed task. type OnTimeOut struct { Callback func(time.Time, WriteCloser) Ctx context.Context } // NewOnTimeOut returns OnTimeOut. func NewOnTimeOut(ctx context.Context, cb func(time.Time, WriteCloser)) *OnTimeOut { return &OnTimeOut{ Callback: cb, Ctx: ctx, } } // Hashable is a interface for hashable object. type Hashable interface { HashCode() int32 } const intSize = unsafe.Sizeof(1) func hashCode(k interface{}) uint32 { var code uint32 h := fnv.New32a() switch v := k.(type) { case bool: h.Write((*((*[1]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case int: h.Write((*((*[intSize]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case int8: h.Write((*((*[1]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case int16: h.Write((*((*[2]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case int32: h.Write((*((*[4]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case int64: h.Write((*((*[8]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case uint: h.Write((*((*[intSize]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case uint8: h.Write((*((*[1]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case uint16: h.Write((*((*[2]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case uint32: h.Write((*((*[4]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case uint64: h.Write((*((*[8]byte)(unsafe.Pointer(&v))))[:]) code = h.Sum32() case string: h.Write([]byte(v)) code = h.Sum32() case Hashable: c := v.HashCode() h.Write((*((*[4]byte)(unsafe.Pointer(&c))))[:]) code = h.Sum32() default: panic("key not hashable") } return code } func isNil(v interface{}) bool { if v == nil { return true } rv := reflect.ValueOf(v) kd := rv.Type().Kind() switch kd { case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice: return rv.IsNil() default: return false } } func printStack() { var buf [4096]byte n := runtime.Stack(buf[:], false) os.Stderr.Write(buf[:n]) }