예제 #1
0
func (s *Semaphore) AcquireTimeout(timeout time.Duration) bool {
	done := make(chan bool, 1)
	// Gate used to communicate between the threads and decide what the result
	// is. If the main thread decides, we have timed out, otherwise we succeed.
	decided := new(int32)
	go func() {
		s.Acquire()
		if atomic.SwapInt32(decided, 1) == 0 {
			done <- true
		} else {
			// If we already decided the result, and this thread did not win
			s.Release()
		}
	}()
	select {
	case <-done:
		return true
	case <-time.NewTimer(timeout).C:
		if atomic.SwapInt32(decided, 1) == 1 {
			// The other thread already decided the result
			return true
		}
		return false
	}
}
예제 #2
0
파일: kv.go 프로젝트: portworx/kvdb
func watchUpdate(kv kvdb.Kvdb, data *watchData) error {
	var err error
	var kvp *kvdb.KVPair

	data.reader, data.writer = 0, 0
	atomic.AddInt32(&data.writer, 1)
	// whichKey = 1 : key
	// whichKey = 0 : otherKey
	atomic.SwapInt32(&data.whichKey, 1)
	data.action = kvdb.KVCreate
	fmt.Printf("-")
	kvp, err = kv.Create(data.key, []byte("bar"), 0)
	for i := 0; i < data.iterations && err == nil; i++ {
		fmt.Printf("-")

		for data.writer != data.reader {
			time.Sleep(time.Millisecond * 100)
		}
		atomic.AddInt32(&data.writer, 1)
		data.action = kvdb.KVSet
		kvp, err = kv.Put(data.key, []byte("bar"), 0)

		data.updateIndex = kvp.KVDBIndex
		assert.NoError(data.t, err, "Unexpected error in Put")
	}

	fmt.Printf("-")
	for data.writer != data.reader {
		time.Sleep(time.Millisecond * 100)
	}
	atomic.AddInt32(&data.writer, 1)
	// Delete key
	data.action = kvdb.KVDelete
	kv.Delete(data.key)

	fmt.Printf("-")
	for data.writer != data.reader {
		time.Sleep(time.Millisecond * 100)
	}
	atomic.AddInt32(&data.writer, 1)

	atomic.SwapInt32(&data.whichKey, 0)
	data.action = kvdb.KVDelete
	// Delete otherKey
	kv.Delete(data.otherKey)

	fmt.Printf("-")
	for data.writer != data.reader {
		time.Sleep(time.Millisecond * 100)
	}
	atomic.AddInt32(&data.writer, 1)

	atomic.SwapInt32(&data.whichKey, 1)
	data.action = kvdb.KVCreate
	_, err = kv.Create(data.key, []byte(data.stop), 0)

	return err
}
예제 #3
0
func (b *Buffer) finishPut() {
	atomic.AddInt32(&b.ring.wpos, 1)
	atomic.CompareAndSwapInt32(&b.ring.wpos, b.ring.size, 0)

	atomic.SwapInt32(&b.readonly, 1)
	b.lock.Unlock()
}
예제 #4
0
func (this *AtomicBoolean) Set(val bool) bool {
	var b int32 = 0
	if val {
		b = 1
	}
	return atomic.SwapInt32((*int32)(this), b) != 0
}
예제 #5
0
func (mailbox *endpointWriterMailbox) processMessages() {
	//we are about to start processing messages, we can safely reset the message flag of the mailbox
	atomic.StoreInt32(&mailbox.hasMoreMessages, mailboxHasNoMessages)
	batchSize := mailbox.batchSize
	done := false

	for !done {
		if sysMsg, ok := mailbox.systemMailbox.Pop(); ok {

			first := sysMsg.(actor.SystemMessage)
			mailbox.systemInvoke(first)
		} else if userMsg, ok := mailbox.userMailbox.PopMany(batchSize); ok {

			mailbox.userInvoke(userMsg)
		} else {
			done = true
			break
		}
		runtime.Gosched()
	}

	//set mailbox to idle
	atomic.StoreInt32(&mailbox.schedulerStatus, mailboxIdle)
	//check if there are still messages to process (sent after the message loop ended)
	if atomic.SwapInt32(&mailbox.hasMoreMessages, mailboxHasNoMessages) == mailboxHasMoreMessages {
		mailbox.schedule()
	}

}
예제 #6
0
func (mailbox *unboundedMailbox) processMessages() {
	//we are about to start processing messages, we can safely reset the message flag of the mailbox
	atomic.StoreInt32(&mailbox.hasMoreMessages, mailboxHasNoMessages)

	done := false
	for !done {
		//process x messages in sequence, then exit
		for i := 0; i < mailbox.throughput; i++ {
			if sysMsg, ok := mailbox.systemMailbox.Pop(); ok {
				sys, _ := sysMsg.(SystemMessage)
				mailbox.systemInvoke(sys)
			} else if userMsg, ok := mailbox.userMailbox.Pop(); ok {

				mailbox.userInvoke(userMsg)
			} else {
				done = true
				break
			}
		}
		runtime.Gosched()
	}

	//set mailbox to idle
	atomic.StoreInt32(&mailbox.schedulerStatus, mailboxIdle)
	//check if there are still messages to process (sent after the message loop ended)
	if atomic.SwapInt32(&mailbox.hasMoreMessages, mailboxHasNoMessages) == mailboxHasMoreMessages {
		mailbox.schedule()
	}

}
예제 #7
0
// Implement kanzi.InputStream interface
func (this *CompressedInputStream) Close() error {
	if atomic.SwapInt32(&this.closed, 1) == 1 {
		return nil
	}

	if _, err := this.ibs.Close(); err != nil {
		return err
	}

	// Release resources
	this.maxIdx = 0
	this.data = EMPTY_BYTE_SLICE

	for i := range this.buffers {
		this.buffers[i] = EMPTY_BYTE_SLICE
	}

	for _, c := range this.syncChan {
		if c != nil {
			close(c)
		}
	}

	close(this.resChan)
	return nil
}
예제 #8
0
func (this *CompressedOutputStream) Close() error {
	if atomic.SwapInt32(&this.closed, 1) == 1 {
		return nil
	}

	if this.curIdx > 0 {
		if err := this.processBlock(); err != nil {
			return err
		}

		this.curIdx = 0
	}

	// Write end block of size 0
	this.obs.WriteBits(SMALL_BLOCK_MASK, 8)

	if _, err := this.obs.Close(); err != nil {
		return err
	}

	// Release resources
	this.data = EMPTY_BYTE_SLICE

	for i := range this.buffers {
		this.buffers[i] = EMPTY_BYTE_SLICE
	}

	for _, c := range this.channels {
		close(c)
	}

	return nil
}
예제 #9
0
func (pc *SocketClient) Close() {
	pc.changes.Lock()
	defer pc.changes.Unlock()

	if atomic.SwapInt32(&pc.state, SocketClosed) != SocketClosed {
		close(pc.writeQueue)
	}
}
예제 #10
0
파일: cacher.go 프로젝트: Timka21213/cacher
// functions for monitoring internals
func monitor(mon *mylib.Mmon, boss mylib.Boss) {
	// just pick up first sender all the time, kiss
	sender := boss.Senders[0]
	ticker := time.Tick(1000 * time.Millisecond)
	last := time.Now()
	for {
		select {
		case <-ticker:
			//			log("debug", fmt.Sprintf("sending to %s..", sender.host))
			curr_time := time.Now()
			if curr_time.Unix() > last.Unix() {
				send_mon_data(atomic.SwapInt32(&mon.Send, 0), atomic.SwapInt32(&mon.Rcv, 0), atomic.SwapInt32(&mon.Conn, 0), boss.Port, curr_time, sender)
				last = curr_time
			}
		}
	}
}
예제 #11
0
func (t *Terminal) Close() error {
	if atomic.SwapInt32(&t.closed, 1) != 0 {
		return nil
	}
	t.stopChan <- struct{}{}
	t.wg.Wait()
	return t.ExitRawMode()
}
예제 #12
0
파일: TopRanker.go 프로젝트: dreyk/dtests
func (c *Cache) monitor() {
	tick := time.Tick(10 * time.Second)
	start := time.Now()
	for {
		select {
		case <-tick:
			in := atomic.SwapInt32(&c.inCache, 0)
			out := atomic.SwapInt32(&c.outCache, 0)
			all := atomic.SwapInt32(&c.requestCount, 0)
			now := time.Now()
			delta := now.Sub(start).Nanoseconds()
			speed := int64(all) * 1000000000 / int64(delta)
			log.Printf("Speed %d. In: %d, Out: %d, All: %d\n", speed, in, out, all)
			start = now
		}
	}
}
예제 #13
0
func (b *Buffer) lastDo() {
	if b.index+1 == b.ring.size {
		atomic.StoreInt32(&b.ring.rpos, 0)
	} else {
		atomic.StoreInt32(&b.ring.rpos, b.index+1)
	}

	atomic.SwapInt32(&b.readonly, 0)
}
예제 #14
0
func (b *AtomicBool) Swap(v bool) bool {
	var n AtomicBool

	if v {
		n = TRUE
	}

	return atomic.SwapInt32((*int32)(unsafe.Pointer(b)), int32(n)) != int32(FALSE)
}
예제 #15
0
파일: node_id.go 프로젝트: knz/cockroach
// Set sets the current node ID. If it is already set, the value must match.
func (n *NodeIDContainer) Set(ctx context.Context, val roachpb.NodeID) {
	if val <= 0 {
		log.Fatalf(ctx, "trying to set invalid NodeID: %d", val)
	}
	oldVal := atomic.SwapInt32(&n.nodeID, int32(val))
	if oldVal == 0 {
		log.Infof(ctx, "NodeID set to %d", val)
	} else if oldVal != int32(val) {
		log.Fatalf(ctx, "different NodeIDs set: %d, then %d", oldVal, val)
	}
}
예제 #16
0
파일: terminal.go 프로젝트: ryane/terraform
func (t *Terminal) Close() error {
	if atomic.SwapInt32(&t.closed, 1) != 0 {
		return nil
	}
	if closer, ok := t.cfg.Stdin.(io.Closer); ok {
		closer.Close()
	}
	close(t.stopChan)
	t.wg.Wait()
	return t.ExitRawMode()
}
예제 #17
0
func (s *Server) Close() {
	atomic.SwapInt32(s.closed, 1)

	s.roomsMu.Lock()
	for _, clients := range s.rooms {
		for _, client := range clients {
			atomic.StoreInt32(client.closed, 1)
			client.Close()
		}
	}
	s.roomsMu.Unlock()
}
예제 #18
0
파일: block.go 프로젝트: allmad/madq
func (i *Instance) Close() bool {
	if atomic.SwapInt32(&i.closed, 1) != 0 {
		return false
	}
	i.Lock()
	for idx, fc := range i.slot {
		fc.done()
		i.slot[idx] = nil
	}
	i.Unlock()
	return true
}
예제 #19
0
func (b *Buffer) nextPut() *Buffer {
	atomic.AddInt32(&b.ring.wpos, 1)
	atomic.CompareAndSwapInt32(&b.ring.wpos, b.ring.size, 0)

	next := b.ring.buffers[b.ring.wpos]
	next.preparePut()

	atomic.SwapInt32(&b.readonly, 1)
	b.lock.Unlock()

	return next
}
예제 #20
0
파일: block.go 프로젝트: allmad/madq
func (i *Instance) Delete(close bool) error {
	if !i.Close() {
		return nil
	}
	if err := os.RemoveAll(i.root); err != nil {
		return logex.Trace(err)
	}
	if !close { // reopen
		os.MkdirAll(i.root, 0777)
		atomic.SwapInt32(&i.closed, 0)
	}
	return nil
}
예제 #21
0
func main() {
	var a int32 = 10
	atomic.AddInt32(&a, 63)
	b := atomic.SwapInt32(&a, 44)
	fmt.Println(b)
	fmt.Println(a)
	if atomic.CompareAndSwapInt32(&a, 10, 12) {
		fmt.Println(a)
		fmt.Println("ok")
	} else {
		fmt.Println("err")
	}
}
예제 #22
0
// handleGoAway is invokde for a typeGoAway frame
func (s *Session) handleGoAway(hdr header) error {
	code := hdr.Length()
	switch code {
	case goAwayNormal:
		atomic.SwapInt32(&s.remoteGoAway, 1)
	case goAwayProtoErr:
		s.logger.Printf("[ERR] yamux: received protocol error go away")
		return fmt.Errorf("yamux protocol error")
	case goAwayInternalErr:
		s.logger.Printf("[ERR] yamux: received internal error go away")
		return fmt.Errorf("remote yamux internal error")
	default:
		s.logger.Printf("[ERR] yamux: received unexpected go away")
		return fmt.Errorf("unexpected go away received")
	}
	return nil
}
예제 #23
0
func (poll *Polling) onPollRequest(req *Request) {
	res := req.res

	if atomic.SwapInt32(&poll.reqGuard, 1) != 0 {
		debug("request overlap")
		poll.onError("overlap from client", "")
		res.WriteHeader(500)
		return
	}
	defer atomic.StoreInt32(&poll.reqGuard, 0)
	debug("setting request")

	timeout := make(chan bool, 1)

	select {
	case poll.readyCh <- true:
	default:
	}

	poll.Emit("drain")

	if poll.shouldClose != nil {
		poll.tryWritable(func() {
			debug("triggering empty send to append close packet")
			poll.send([]*parser.Packet{&noopPkt})
		}, nil)
	}

	var data []byte = nil
	select {
	case data = <-poll.writeCh:
	case <-timeout:
	}
	poll.doWrite(req, data)
	close(timeout)

	select {
	case <-poll.readyCh:
	default:
	}
}
예제 #24
0
파일: kv.go 프로젝트: portworx/kvdb
func watchKey(kv kvdb.Kvdb, t *testing.T) {
	fmt.Println("\nwatchKey")

	watchData := watchData{
		t:          t,
		key:        "tree/key1",
		otherKey:   "tree/otherKey1",
		stop:       "stop",
		iterations: 2,
	}

	kv.Delete(watchData.key)
	kv.Delete(watchData.otherKey)
	// First create a key. We should not get update for this create.
	_, err := kv.Create(watchData.otherKey, []byte("bar"), 0)
	// Let the create operation finish and then start the watch
	time.Sleep(time.Second)

	err = kv.WatchKey(watchData.otherKey, 0, &watchData, watchFn)
	if err != nil {
		fmt.Printf("Cannot test watchKey: %v\n", err)
		return
	}

	err = kv.WatchKey(watchData.key, 0, &watchData, watchFn)
	if err != nil {
		fmt.Printf("Cannot test watchKey: %v\n", err)
		return
	}

	go watchUpdate(kv, &watchData)

	for watchData.watchStopped == false {
		time.Sleep(time.Millisecond * 100)
	}

	// Stop the second watch
	atomic.SwapInt32(&watchData.whichKey, 0)
	watchData.action = kvdb.KVCreate
	_, err = kv.Create(watchData.otherKey, []byte(watchData.stop), 0)
}
예제 #25
0
파일: polling.go 프로젝트: kaicheng/goport
func (poll *Polling) onDataRequest(req *Request) {
	res := req.res

	if atomic.SwapInt32(&poll.dataGuard, 1) != 0 {
		debug("data request overlap from client")
		poll.onError("data request overlap from client", "")
		res.WriteHeader(500)
		return
	}

	chunks := new(bytes.Buffer)
	buffer := make([]byte, 4096)
	for {
		length, err := req.httpReq.Body.Read(buffer)
		if length+chunks.Len() > poll.maxHTTPBufferSize {
			chunks.Reset()
			req.httpReq.Body.Close()
			req.httpReq.Close = true
		} else {
			chunks.Write(buffer[:length])
		}
		if err != nil {
			break
		}
	}

	debug("data request onEnd ok. data.len = ", chunks.Len())
	go poll.onData(chunks.Next(chunks.Len()))

	res.Header().Set("Content-Length", "2")
	res.Header().Set("Content-Type", "text/html")
	poll.headers(req)
	res.WriteHeader(200)
	res.Write([]byte("ok"))

	atomic.StoreInt32(&poll.dataGuard, 0)
}
예제 #26
0
// goAway is used to send a goAway message
func (s *Session) goAway(reason uint32) header {
	atomic.SwapInt32(&s.localGoAway, 1)
	hdr := header(make([]byte, headerSize))
	hdr.encode(typeGoAway, 0, 0, reason)
	return hdr
}
예제 #27
0
// Swap sets the value of the boolean to true or false and returns the old value
func (b *Bool) Swap(value bool) bool {
	if value {
		return atomic.SwapInt32(&b.value, 1) != 0
	}
	return atomic.SwapInt32(&b.value, 0) != 0
}
예제 #28
0
파일: atomic.go 프로젝트: sgotti/stolon
// Swap atomically swaps the wrapped int32 and returns the old value.
func (i *Int32) Swap(n int32) int32 {
	return atomic.SwapInt32(&i.v, n)
}
예제 #29
0
func SwapInt32(addr *int32, new int32) int32 {
	return orig.SwapInt32(addr, new)
}
예제 #30
0
func lock() {
	for atomic.SwapInt32(&mutex, 1) == 1 {
	} // While it returns 1
}