mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
WIP: Some incorrect things, and logging, will clean up later
What's done here: - Call releaseLock() on the stdin reader, which immediately cancels any active reads and prevents new ones. - Adjust BetterReader to pass releaseLock() on, and handle the input ending, and expose how much input was read into a buffer if it's partially filled. - Add an error message when the one user of read(opt_buffer) gets too small a buffer. That last one is readline trying to read 1 byte, and we currently infinitely loop on that after exiting a process. So this is definitely not correct but it feels like it's the right direction.
This commit is contained in:
parent
27fb88fd75
commit
d1db4a11ef
@ -34,22 +34,25 @@ export class BetterReader {
|
|||||||
|
|
||||||
const chunk = await this.getChunk_();
|
const chunk = await this.getChunk_();
|
||||||
|
|
||||||
if ( ! opt_buffer ) {
|
if ( ! opt_buffer || ! chunk ) {
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chunks_.push(chunk);
|
this.chunks_.push(chunk);
|
||||||
|
|
||||||
while ( this.getTotalBytesReady_() < opt_buffer.length ) {
|
while ( this.getTotalBytesReady_() < opt_buffer.length ) {
|
||||||
this.chunks_.push(await this.getChunk_())
|
const read_chunk = await this.getChunk_();
|
||||||
|
if ( ! read_chunk ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.chunks_.push(read_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need to handle EOT condition in this loop
|
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
for (;;) {
|
while ( this.chunks_.length > 0 && offset < opt_buffer.length ) {
|
||||||
let item = this.chunks_.shift();
|
let item = this.chunks_.shift();
|
||||||
if ( item === undefined ) {
|
if ( item === undefined ) {
|
||||||
throw new Error('calculation is wrong')
|
break;
|
||||||
}
|
}
|
||||||
if ( offset + item.length > opt_buffer.length ) {
|
if ( offset + item.length > opt_buffer.length ) {
|
||||||
const diff = opt_buffer.length - offset;
|
const diff = opt_buffer.length - offset;
|
||||||
@ -58,16 +61,16 @@ export class BetterReader {
|
|||||||
}
|
}
|
||||||
opt_buffer.set(item, offset);
|
opt_buffer.set(item, offset);
|
||||||
offset += item.length;
|
offset += item.length;
|
||||||
|
|
||||||
if ( offset == opt_buffer.length ) break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return opt_buffer.length;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChunk_() {
|
async getChunk_() {
|
||||||
if ( this.chunks_.length === 0 ) {
|
if ( this.chunks_.length === 0 ) {
|
||||||
const { value } = await this.delegate.read();
|
const { value } = await this.delegate.read().catch( ( err ) => {
|
||||||
|
return {};
|
||||||
|
});
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +90,11 @@ export class BetterReader {
|
|||||||
getTotalBytesReady_ () {
|
getTotalBytesReady_ () {
|
||||||
return this.chunks_.reduce((sum, chunk) => sum + chunk.length, 0);
|
return this.chunks_.reduce((sum, chunk) => sum + chunk.length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async releaseLock() {
|
||||||
|
console.log('cancelling betterreader, delegate is', this.delegate);
|
||||||
|
await this.delegate.releaseLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,7 +24,9 @@ export class Coupler {
|
|||||||
Does not close the write stream when the read stream is closed.
|
Does not close the write stream when the read stream is closed.
|
||||||
`
|
`
|
||||||
|
|
||||||
constructor (source, target) {
|
constructor (source, target, debug) {
|
||||||
|
this.debug = debug || false;
|
||||||
|
console.log('creating coupler. source is', this.source);
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.on_ = true;
|
this.on_ = true;
|
||||||
@ -39,8 +41,9 @@ export class Coupler {
|
|||||||
on () { this.on_ = true; }
|
on () { this.on_ = true; }
|
||||||
|
|
||||||
close () {
|
close () {
|
||||||
|
if (this.debug) console.log('closing coupler. source is', this.source);
|
||||||
|
this.source.releaseLock();
|
||||||
this.closed_.resolve({
|
this.closed_.resolve({
|
||||||
value: undefined,
|
|
||||||
done: true,
|
done: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ export class PreparedCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const internal_input_pipe = new Pipe();
|
const internal_input_pipe = new Pipe();
|
||||||
const valve = new Coupler(in_, internal_input_pipe.in);
|
const valve = new Coupler(in_, internal_input_pipe.in, true);
|
||||||
in_ = internal_input_pipe.out;
|
in_ = internal_input_pipe.out;
|
||||||
|
|
||||||
// simple naive implementation for now
|
// simple naive implementation for now
|
||||||
|
@ -57,7 +57,10 @@ const ReadlineProcessorBuilder = builder => builder
|
|||||||
const { locals, externs } = ctx;
|
const { locals, externs } = ctx;
|
||||||
|
|
||||||
const byteBuffer = new Uint8Array(1);
|
const byteBuffer = new Uint8Array(1);
|
||||||
await externs.in_.read(byteBuffer);
|
const bytesRead = await externs.in_.read(byteBuffer);
|
||||||
|
if (bytesRead !== 1) {
|
||||||
|
console.warn('Failed to read byte in get-byte state of readline');
|
||||||
|
}
|
||||||
locals.byteBuffer = byteBuffer;
|
locals.byteBuffer = byteBuffer;
|
||||||
locals.byte = byteBuffer[0];
|
locals.byte = byteBuffer[0];
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user