git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit 3caa963721b6de8700ae2769edf1ce8f78bc0718

check for cyclic waits

wanderer committed on 5/7/2017, 10:37:55 AM
Parent: 1585b228b98ee11398442d6ae9697882ea7360dd

Files changed

index.jschanged
kernel.jschanged
portManager.jschanged
tests/index.jschanged
index.jsView
@@ -31,11 +31,11 @@
3131 }
3232
3333 // given a port, wait untill its source contract has reached the threshold
3434 // tick count
35- async wait (port, threshold) {
35+ async wait (port, threshold, fromPort) {
3636 let kernel = await this.getInstance(port)
37- return kernel.wait(threshold)
37+ return kernel.wait(threshold, fromPort)
3838 }
3939
4040 async createInstance (type, state, entryPort, parentPort) {
4141 const VM = this._VMs[type]
@@ -60,9 +60,9 @@
6060 /**
6161 * opts.entryPort
6262 * opts.parentPort
6363 */
64- createInstanceFromPort (entryPort, parentPort) {
64+ async createInstanceFromPort (entryPort, parentPort) {
6565 const state = entryPort.link['/']
6666 return this.createInstance(entryPort.type, state, entryPort, parentPort)
6767 }
6868
@@ -74,9 +74,10 @@
7474 async generateID (port) {
7575 if (!port || !port.id) {
7676 return null
7777 }
78- let id = await this.graph.flush(port.id)
78+ let id = Object.assign({}, port.id)
79+ id = await this.graph.flush(id)
7980 id = id['/']
8081 if (Buffer.isBuffer(id)) {
8182 id = multibase.encode('base58btc', id).toString()
8283 }
kernel.jsView
@@ -27,9 +27,12 @@
2727 })
2828 this.on('result', this._runNextMessage)
2929 this.on('idle', () => {
3030 while (!this._waitingQueue.isEmpty()) {
31- this._waitingQueue.poll().resolve()
31+ const waiter = this._waitingQueue.poll()
32+ this.wait(waiter.ticks, waiter.from).then(ticks => {
33+ waiter.resolve(ticks)
34+ })
3235 }
3336 })
3437 }
3538
@@ -50,8 +53,9 @@
5053 this.emit(vmState, message)
5154 }
5255
5356 async _runNextMessage () {
57+ // console.log('next message', this.ticks, this.entryPort)
5458 const message = await this.ports.getNextMessage()
5559 // if the vm is paused and it gets a message; save that message for use when the VM is resumed
5660 if (message && this.vmState === 'paused') {
5761 this.ports._portMap(message._fromPort).unshfit(message)
@@ -98,30 +102,35 @@
98102 exceptionError: e
99103 }
100104 clearObject(this.state)
101105 Object.assign(this.state, oldState)
106+ console.log(e)
102107 }
103108
104109 this.emit('result', result)
105110 return result
106111 }
107112
108113 // returns a promise that resolves once the kernel hits the threshould tick
109114 // count
110- async wait (threshold) {
111- return new Promise((resolve, reject) => {
112- if (this.vmState === 'idle' || threshold <= this.ticks) {
113- resolve(this.ticks)
114- } else {
115+ async wait (threshold, fromPort) {
116+ if (threshold <= this.ticks) {
117+ return this.ticks
118+ } else if (this.vmState === 'idle') {
119+ return this.ports.wait(threshold, fromPort)
120+ } else {
121+ return new Promise((resolve, reject) => {
115122 this._waitingQueue.add({
116123 threshold: threshold,
117- resolve: resolve
124+ resolve: resolve,
125+ from: fromPort
118126 })
119- }
120- })
127+ })
128+ }
121129 }
122130
123131 incrementTicks (count) {
132+ console.log('update ticks')
124133 this.ticks += count
125134 while (!this._waitingQueue.isEmpty()) {
126135 const waiter = this._waitingQueue.peek()
127136 if (waiter.threshold > this.ticks) {
@@ -134,9 +143,8 @@
134143
135144 async createPort (type, name) {
136145 const VM = this.hypervisor._VMs[type]
137146 const parentId = this.entryPort ? this.entryPort.id : null
138-
139147 const portRef = {
140148 'messages': [],
141149 'id': {
142150 '/': {
@@ -151,14 +159,12 @@
151159 }
152160
153161 // create the port instance
154162 await this.ports.set(name, portRef)
155-
156163 // incerment the nonce
157164 const nonce = new BN(this.state.nonce)
158165 nonce.iaddn(1)
159166 this.state.nonce = nonce.toArray()
160-
161167 return portRef
162168 }
163169
164170 async send (portRef, message) {
@@ -167,8 +173,9 @@
167173 portInstance.hasSent = true
168174 } catch (e) {
169175 throw new Error('invalid port referance, which means the port that the port was either moved or destoried')
170176 }
177+
171178 const id = await this.hypervisor.generateID(this.entryPort)
172179 message._fromPort = id
173180 message._ticks = this.ticks
174181
portManager.jsView
@@ -66,24 +66,27 @@
6666 return this.ports[key]
6767 }
6868
6969 // waits till all ports have reached a threshold tick count
70- async wait (threshold) {
70+ async wait (threshold, fromPort) {
71+ // console.log('wait', threshold, 'id', this.entryPort)
7172 // find the ports that have a smaller tick count then the threshold tick count
7273 const unkownPorts = [...this._portMap].filter(([id, port]) => {
73- return (port.hasSent || port.name === ENTRY) && port.ticks < threshold
74+ return (port.hasSent || port.name === ENTRY) &&
75+ port.ticks < threshold &&
76+ fromPort !== port
7477 })
7578
7679 const promises = unkownPorts.map(async ([id, port]) => {
7780 const portObj = port.name === ENTRY ? this.parentPort : this.ports[port.name]
7881 // update the port's tick count
79- port.ticks = await this.hypervisor.wait(portObj, threshold)
82+ port.ticks = await this.hypervisor.wait(portObj, threshold, this.entryPort)
8083 })
8184 return Promise.all(promises)
8285 }
8386
8487 async getNextMessage () {
85- await this.wait(this.kernel.ticks)
88+ await this.wait(this.kernel.ticks, this.entryPort)
8689 const portMap = [...this._portMap].reduce(messageArbiter)
8790 if (portMap) {
8891 return portMap[1].shift()
8992 }
tests/index.jsView
@@ -22,9 +22,9 @@
2222 console.log(err)
2323 })
2424
2525 node.on('start', () => {
26- tape('basic', async t => {
26+ tape.only('basic', async t => {
2727 const message = new Message()
2828 const expectedState = {
2929 '/': 'zdpuAntkdU7yBJojcBT5Q9wBhrK56NmLnwpHPKaEGMFnAXpv7'
3030 }
@@ -47,9 +47,9 @@
4747 t.deepEquals(stateRoot, expectedState, 'expected root!')
4848 t.end()
4949 })
5050
51- tape.only('one child contract', async t => {
51+ tape('one child contract', async t => {
5252 let message = new Message()
5353 const expectedState = { '/': 'zdpuAqtY43BMaTCB5nTt7kooeKAWibqGs44Uwy9jJQHjTnHRK' }
5454 let hasResolved = false
5555
@@ -68,9 +68,13 @@
6868
6969 class testVMContainer extends BaseContainer {
7070 async run (m) {
7171 const port = await this.kernel.createPort('test2', 'child')
72- await this.kernel.send(port, m)
72+ try {
73+ await this.kernel.send(port, m)
74+ } catch (e) {
75+ console.log(e)
76+ }
7377 this.kernel.incrementTicks(1)
7478 }
7579 }
7680

Built with git-ssb-web