| // 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"; |
| } |