blob: d26e536b7c4b40a4d14cae76bc4cb8ce9bfd3583 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.io;
// This list must be kept in sync with the list in runtime/bin/io_service.h
const int _FILE_EXISTS = 0;
const int _FILE_CREATE = 1;
const int _FILE_DELETE = 2;
const int _FILE_RENAME = 3;
const int _FILE_COPY = 4;
const int _FILE_OPEN = 5;
const int _FILE_RESOLVE_SYMBOLIC_LINKS = 6;
const int _FILE_CLOSE = 7;
const int _FILE_POSITION = 8;
const int _FILE_SET_POSITION = 9;
const int _FILE_TRUNCATE = 10;
const int _FILE_LENGTH = 11;
const int _FILE_LENGTH_FROM_PATH = 12;
const int _FILE_LAST_ACCESSED = 13;
const int _FILE_SET_LAST_ACCESSED = 14;
const int _FILE_LAST_MODIFIED = 15;
const int _FILE_SET_LAST_MODIFIED = 16;
const int _FILE_FLUSH = 17;
const int _FILE_READ_BYTE = 18;
const int _FILE_WRITE_BYTE = 19;
const int _FILE_READ = 20;
const int _FILE_READ_INTO = 21;
const int _FILE_WRITE_FROM = 22;
const int _FILE_CREATE_LINK = 23;
const int _FILE_DELETE_LINK = 24;
const int _FILE_RENAME_LINK = 25;
const int _FILE_LINK_TARGET = 26;
const int _FILE_TYPE = 27;
const int _FILE_IDENTICAL = 28;
const int _FILE_STAT = 29;
const int _FILE_LOCK = 30;
const int _SOCKET_LOOKUP = 31;
const int _SOCKET_LIST_INTERFACES = 32;
const int _SOCKET_REVERSE_LOOKUP = 33;
const int _DIRECTORY_CREATE = 34;
const int _DIRECTORY_DELETE = 35;
const int _DIRECTORY_EXISTS = 36;
const int _DIRECTORY_CREATE_TEMP = 37;
const int _DIRECTORY_LIST_START = 38;
const int _DIRECTORY_LIST_NEXT = 39;
const int _DIRECTORY_LIST_STOP = 40;
const int _DIRECTORY_RENAME = 41;
const int _SSL_PROCESS_FILTER = 42;
class _IOService {
static Future<Object> _dispatch(int request, List<Object> data) {
int id;
do {
id = _getNextId();
} while (_messageMap.containsKey(id));
int index = id % _SERVICE_PORT_COUNT;
_initialize(index);
var completer = new Completer<Object>();
_messageMap[id] = completer;
try {
_servicePort[index].send([id, _replyToPort, request, data]);
} catch (error) {
_messageMap.remove(id).complete(error);
if (_messageMap.length == 0) {
_finalize();
}
}
return completer.future;
}
static const int _SERVICE_PORT_COUNT = 32;
static List<SendPort> _servicePort = new List<SendPort>(_SERVICE_PORT_COUNT);
static RawReceivePort _receivePort;
static SendPort _replyToPort;
static Map<int, Completer<Object> > _messageMap = {};
static int _id = 0;
static void _initialize(int index) {
if (_servicePort[index] == null) {
_servicePort[index] = _newServicePort();
}
if (_receivePort == null) {
_receivePort = new RawReceivePort();
_replyToPort = _receivePort.sendPort;
_receivePort.handler = (data) {
assert(data is List);
assert(data.length == 2);
_messageMap.remove(data[0] as int).complete(data[1]);
if (_messageMap.length == 0) {
_finalize();
}
};
}
}
static void _finalize() {
_id = 0;
_receivePort.close();
_receivePort = null;
}
static int _getNextId() {
if (_id == 0x7FFFFFFF) _id = 0;
return _id++;
}
static SendPort _newServicePort() native "IOService_NewServicePort";
}