Fixed EXC_BAD_ACCESS
This commit is contained in:
parent
311dede079
commit
2409e06e6a
10 changed files with 75 additions and 71 deletions
11
Makefile
11
Makefile
|
@ -2,7 +2,13 @@ CXX=clang
|
|||
HTTP_PARSER=.dart_tool/build_native/third_party/angel_wings.http_parser
|
||||
CXX_INCLUDES=-I$(HTTP_PARSER) -I$(DART_SDK)/include
|
||||
|
||||
.PHONY: clean debug
|
||||
.PHONY: clean debug macos all
|
||||
|
||||
all:
|
||||
printf 'Available targets:\n'\
|
||||
' * `debug` - Builds a debug library on MacOS\n'\
|
||||
' * `example` - Runs example/main.dart in LLDB on MacOS\n'\
|
||||
' * `macos` - Builds a release-mode library on MacOS\n'
|
||||
|
||||
clean:
|
||||
find lib -name "*.a" -delete
|
||||
|
@ -12,6 +18,9 @@ clean:
|
|||
debug:
|
||||
$(MAKE) lib/src/libwings.dylib CXXFLAGS="-g -DDEBUG=1"
|
||||
|
||||
macos:
|
||||
$(MAKE) lib/src/libwings.dylib
|
||||
|
||||
example: debug
|
||||
lldb -o "target create dart" \
|
||||
-o "process launch --stop-at-entry example/main.dart" \
|
||||
|
|
|
@ -5,7 +5,6 @@ import 'package:angel_framework/angel_framework.dart';
|
|||
import 'package:angel_wings/angel_wings.dart';
|
||||
|
||||
main() async {
|
||||
if (false)
|
||||
for (int i = 1; i < Platform.numberOfProcessors; i++) {
|
||||
var onError = new ReceivePort();
|
||||
Isolate.spawn(isolateMain, i, onError: onError.sendPort);
|
||||
|
@ -18,7 +17,7 @@ main() async {
|
|||
|
||||
void isolateMain(int id) {
|
||||
var app = new Angel();
|
||||
var wings = new AngelWings(app, shared: id > 0, useZone: false);
|
||||
var wings = new AngelWings(app, shared: true, useZone: false);
|
||||
|
||||
var old = app.errorHandler;
|
||||
app.errorHandler = (e, req, res) {
|
||||
|
|
|
@ -13,7 +13,7 @@ import 'package:http_parser/http_parser.dart';
|
|||
import 'package:json_god/json_god.dart' as god;
|
||||
import 'package:mock_request/mock_request.dart';
|
||||
import 'package:pool/pool.dart';
|
||||
import 'package:pooled_map/pooled_map.dart';
|
||||
//import 'package:pooled_map/pooled_map.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
|
|
@ -34,12 +34,11 @@ void wings_BindSocket(Dart_NativeArguments arguments)
|
|||
std::string addressStringInstance(addressString);
|
||||
std::lock_guard<std::mutex> lock(serverInfoVectorMutex);
|
||||
|
||||
#if __APPLE__
|
||||
if (false)
|
||||
#else
|
||||
|
||||
if (shared)
|
||||
#endif
|
||||
{
|
||||
#if __APPLE__
|
||||
#else
|
||||
for (unsigned long i = 0; i < serverInfoVector.size(); i++)
|
||||
{
|
||||
WingsServerInfo *server_info = serverInfoVector.at(i);
|
||||
|
@ -50,6 +49,7 @@ void wings_BindSocket(Dart_NativeArguments arguments)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (existingIndex > -1)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <dart_native_api.h>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
//#include <iostream>
|
||||
#include <cstdio>
|
||||
#include "wings.h"
|
||||
#include "wings_thread.h"
|
||||
|
@ -56,9 +56,9 @@ void handleMessage(Dart_Port destPortId, Dart_CObject *message)
|
|||
else
|
||||
{
|
||||
// This is either a send or close message.
|
||||
std::cout << "NVALUES: " << message->value.as_array.length << std::endl;
|
||||
//std::cout << "NVALUES: " << message->value.as_array.length << std::endl;
|
||||
int sockfd = (int)get_int(message->value.as_array.values[0]);
|
||||
printf("FD: %d\n", sockfd);
|
||||
//printf("FD: %d\n", sockfd);
|
||||
|
||||
if (message->value.as_array.length >= 2)
|
||||
{
|
||||
|
@ -69,30 +69,30 @@ void handleMessage(Dart_Port destPortId, Dart_CObject *message)
|
|||
|
||||
if (msg->type == Dart_CObject_kExternalTypedData)
|
||||
{
|
||||
std::cout << "ext typed data" << std::endl;
|
||||
printf("Length: %ld\n", msg->value.as_external_typed_data.length);
|
||||
std::cout << "ptr: " << msg->value.as_typed_data.values << std::endl;
|
||||
//std::cout << "ext typed data" << std::endl;
|
||||
//printf("Length: %ld\n", msg->value.as_external_typed_data.length);
|
||||
//std::cout << "ptr: " << msg->value.as_typed_data.values << std::endl;
|
||||
write(sockfd, msg->value.as_external_typed_data.data, (size_t)msg->value.as_external_typed_data.length);
|
||||
}
|
||||
else if (msg->type == Dart_CObject_kTypedData)
|
||||
{
|
||||
std::cout << "regular typed data" << std::endl;
|
||||
printf("Length: %ld\n", msg->value.as_typed_data.length);
|
||||
//std::cout << "regular typed data" << std::endl;
|
||||
//printf("Length: %ld\n", msg->value.as_typed_data.length);
|
||||
write(sockfd, msg->value.as_typed_data.values, (size_t)msg->value.as_typed_data.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "unknown type: " << ((Dart_CObject_Type) msg->type) << std::endl;
|
||||
//std::cout << "unknown type: " << ((Dart_CObject_Type) msg->type) << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "null msg!!!" << std::endl;
|
||||
//std::cout << "null msg!!!" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Close!\n");
|
||||
//printf("Close!\n");
|
||||
close(sockfd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
#ifdef DEBUG
|
||||
#include "dart_debug.h"
|
||||
#endif
|
||||
#include "wings.h"
|
||||
|
||||
void wings_CloseSocket(Dart_NativeArguments arguments)
|
||||
|
@ -20,9 +17,6 @@ void wings_Send(Dart_NativeArguments arguments)
|
|||
void *dataBytes;
|
||||
intptr_t dataLength;
|
||||
|
||||
#ifdef DEBUG
|
||||
HandleError(Dart_Print(sockfdHandle));
|
||||
#endif
|
||||
HandleError(Dart_IntegerToUint64(sockfdHandle, &sockfd));
|
||||
HandleError(Dart_TypedDataAcquireData(dataHandle, &dataType, &dataBytes, &dataLength));
|
||||
write((int)sockfd, dataBytes, (size_t)dataLength);
|
||||
|
|
|
@ -89,12 +89,13 @@ class AngelWings {
|
|||
|
||||
static SendPort _startHttpListener() native "StartHttpListener";
|
||||
|
||||
final Pool _pool = new Pool(1);
|
||||
//final Pool _pool = new Pool(1);
|
||||
|
||||
static void __send(int sockfd, Uint8List data) native "Send";
|
||||
static void _send(int sockfd, Uint8List data) native "Send";
|
||||
|
||||
static void __closeSocket(int sockfd) native "CloseSocket";
|
||||
static void _closeSocket(int sockfd) native "CloseSocket";
|
||||
|
||||
/*
|
||||
void _send(int sockfd, Uint8List data) {
|
||||
// _pool.withResource(() {
|
||||
print('Sending ${[sockfd, data]}');
|
||||
|
@ -113,7 +114,7 @@ class AngelWings {
|
|||
}
|
||||
//});
|
||||
//_pool.withResource(() => __closeSocket(sockfd));
|
||||
}
|
||||
}*/
|
||||
|
||||
AngelWings(this.app, {this.shared: false, this.useZone: true}) {
|
||||
_recv.handler = _handleMessage;
|
||||
|
@ -164,7 +165,7 @@ class AngelWings {
|
|||
}
|
||||
|
||||
void _handleMessage(x) {
|
||||
print('INPUT: $x');
|
||||
//print('INPUT: $x');
|
||||
if (x is String) {
|
||||
close();
|
||||
throw new StateError(x);
|
||||
|
@ -177,11 +178,11 @@ class AngelWings {
|
|||
|
||||
switch (command) {
|
||||
case messageBegin:
|
||||
print('BEGIN $sockfd');
|
||||
//print('BEGIN $sockfd');
|
||||
_staging[sockfd] = new WingsRequestContext._(this, sockfd, app);
|
||||
break;
|
||||
case messageComplete:
|
||||
print('$sockfd in $_staging???');
|
||||
//print('$sockfd in $_staging???');
|
||||
var rq = _staging.remove(sockfd);
|
||||
if (rq != null) {
|
||||
rq._method = methodToString(x[2] as int);
|
||||
|
@ -218,13 +219,13 @@ class AngelWings {
|
|||
}
|
||||
|
||||
Future _handleRequest(WingsRequestContext req) {
|
||||
print('req: $req');
|
||||
//print('req: $req');
|
||||
if (req == null) return new Future.value();
|
||||
var res = new WingsResponseContext._(req)
|
||||
..app = app
|
||||
..serializer = (app.serializer ?? god.serialize)
|
||||
..encoders.addAll(app.encoders);
|
||||
print('Handling fd: ${req._sockfd}');
|
||||
//print('Handling fd: ${req._sockfd}');
|
||||
|
||||
handle() {
|
||||
var path = req.path;
|
||||
|
@ -257,7 +258,7 @@ class AngelWings {
|
|||
|
||||
Future<bool> Function() runPipeline;
|
||||
|
||||
print('Pipeline: $pipeline');
|
||||
//print('Pipeline: $pipeline');
|
||||
for (var handler in pipeline) {
|
||||
if (handler == null) break;
|
||||
|
||||
|
@ -316,7 +317,7 @@ class AngelWings {
|
|||
return handleAngelHttpException(e, trace, req, res);
|
||||
}).catchError((e, StackTrace st) {
|
||||
var trace = new Trace.from(st ?? StackTrace.current).terse;
|
||||
_closeSocket(req);
|
||||
AngelWings._closeSocket(req._sockfd);
|
||||
// Ideally, we won't be in a position where an absolutely fatal error occurs,
|
||||
// but if so, we'll need to log it.
|
||||
if (app.logger != null) {
|
||||
|
@ -354,7 +355,7 @@ class AngelWings {
|
|||
b.writeln();
|
||||
|
||||
_send(req._sockfd, _coerceUint8List(b.toString().codeUnits));
|
||||
_closeSocket(req);
|
||||
AngelWings._closeSocket(req._sockfd);
|
||||
} finally {
|
||||
return null;
|
||||
}
|
||||
|
@ -379,9 +380,9 @@ class AngelWings {
|
|||
/// Sends a response.
|
||||
Future sendResponse(WingsRequestContext req, WingsResponseContext res,
|
||||
{bool ignoreFinalizers: false}) {
|
||||
print('Closing: ${req._sockfd}');
|
||||
//print('Closing: ${req._sockfd}');
|
||||
if (res.willCloseItself) return new Future.value();
|
||||
print('Not self-closing: ${req._sockfd}');
|
||||
//print('Not self-closing: ${req._sockfd}');
|
||||
|
||||
Future finalizers = ignoreFinalizers == true
|
||||
? new Future.value()
|
||||
|
@ -399,7 +400,7 @@ class AngelWings {
|
|||
//request.response.headers.chunkedTransferEncoding = res.chunked ?? true;
|
||||
// TODO: Is there a need to support this?
|
||||
|
||||
print('Buffer: ${res.buffer}');
|
||||
//print('Buffer: ${res.buffer}');
|
||||
List<int> outputBuffer = res.buffer.toBytes();
|
||||
|
||||
if (res.encoders.isNotEmpty) {
|
||||
|
@ -437,7 +438,7 @@ class AngelWings {
|
|||
}
|
||||
}
|
||||
|
||||
print('Create string buffer');
|
||||
//print('Create string buffer');
|
||||
var b = new StringBuffer();
|
||||
b.writeln('HTTP/1.1 ${res.statusCode}');
|
||||
|
||||
|
@ -458,20 +459,20 @@ class AngelWings {
|
|||
}
|
||||
|
||||
b.writeln();
|
||||
print(b);
|
||||
//print(b);
|
||||
|
||||
var bb = new BytesBuilder(copy: false)
|
||||
..add(b.toString().codeUnits)
|
||||
..add(outputBuffer);
|
||||
var buf = _coerceUint8List(bb.takeBytes());
|
||||
print('Output: $buf');
|
||||
//print('Output: $buf');
|
||||
|
||||
return finalizers.then((_) {
|
||||
print('A');
|
||||
//print('A');
|
||||
_send(req._sockfd, buf);
|
||||
print('B');
|
||||
_closeSocket(req);
|
||||
print('C');
|
||||
//print('B');
|
||||
AngelWings._closeSocket(req._sockfd);
|
||||
//print('C');
|
||||
|
||||
if (req.injections.containsKey(PoolResource)) {
|
||||
req.injections[PoolResource].release();
|
||||
|
|
|
@ -13,14 +13,14 @@ class WingsResponseContext extends ResponseContext {
|
|||
if (_isClosed && !_useStream)
|
||||
throw ResponseContext.closed();
|
||||
else if (_useStream)
|
||||
_wings._send(correspondingRequest._sockfd, _coerceUint8List(data));
|
||||
AngelWings._send(correspondingRequest._sockfd, _coerceUint8List(data));
|
||||
else
|
||||
buffer.add(data);
|
||||
}
|
||||
|
||||
@override
|
||||
Future close() {
|
||||
_wings._closeSocket(correspondingRequest);
|
||||
AngelWings._closeSocket(correspondingRequest._sockfd);
|
||||
_isClosed = true;
|
||||
_useStream = false;
|
||||
return super.close();
|
||||
|
@ -77,7 +77,7 @@ class WingsResponseContext extends ResponseContext {
|
|||
}
|
||||
|
||||
return output.forEach(((data) =>
|
||||
_wings._send(correspondingRequest._sockfd, _coerceUint8List(data))));
|
||||
AngelWings._send(correspondingRequest._sockfd, _coerceUint8List(data))));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -147,7 +147,7 @@ class WingsResponseContext extends ResponseContext {
|
|||
|
||||
b.writeln();
|
||||
|
||||
_wings._send(
|
||||
AngelWings._send(
|
||||
correspondingRequest._sockfd, _coerceUint8List(b.toString().codeUnits));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//#include <memory>
|
||||
#include <iostream>
|
||||
//#include <iostream>
|
||||
#include <utility>
|
||||
#include <dart_native_api.h>
|
||||
#include "wings_thread.h"
|
||||
|
@ -86,11 +86,11 @@ int send_string(http_parser *parser, char *str, size_t length, int code, bool as
|
|||
}
|
||||
else
|
||||
{
|
||||
third.type = Dart_CObject_kExternalTypedData;
|
||||
third.type = Dart_CObject_kExternalTypedData;
|
||||
third.value.as_external_typed_data.type = Dart_TypedData_kUint8;
|
||||
third.value.as_external_typed_data.length = length;
|
||||
third.value.as_external_typed_data.data = (uint8_t *)str;
|
||||
third.type = Dart_CObject_kTypedData;
|
||||
third.type = Dart_CObject_kTypedData;
|
||||
third.value.as_typed_data.type = Dart_TypedData_kUint8;
|
||||
third.value.as_typed_data.length = length;
|
||||
third.value.as_typed_data.values = (uint8_t *)str;
|
||||
}
|
||||
|
||||
// Post the string back to Dart...
|
||||
|
@ -118,24 +118,24 @@ int send_oncomplete(http_parser *parser, int code)
|
|||
Dart_CObject minor{};
|
||||
Dart_CObject addr{};
|
||||
sockfd.type = command.type = method.type = major.type = minor.type = Dart_CObject_kInt32;
|
||||
addr.type = Dart_CObject_kExternalTypedData;
|
||||
addr.type = Dart_CObject_kTypedData;
|
||||
sockfd.value.as_int32 = rq->sock;
|
||||
command.value.as_int32 = code;
|
||||
method.value.as_int32 = parser->method;
|
||||
major.value.as_int32 = parser->http_major;
|
||||
minor.value.as_int32 = parser->http_minor;
|
||||
addr.value.as_external_typed_data.type = Dart_TypedData_kUint8;
|
||||
addr.value.as_external_typed_data.length = rq->addr_len;
|
||||
addr.value.as_typed_data.type = Dart_TypedData_kUint8;
|
||||
addr.value.as_typed_data.length = rq->addr_len;
|
||||
|
||||
if (rq->ipv6)
|
||||
{
|
||||
auto *v6 = (sockaddr_in6 *)&rq->addr;
|
||||
addr.value.as_external_typed_data.data = (uint8_t *)v6->sin6_addr.s6_addr;
|
||||
addr.value.as_typed_data.values = (uint8_t *)v6->sin6_addr.s6_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto *v4 = (sockaddr_in *)&rq->addr;
|
||||
addr.value.as_external_typed_data.data = (uint8_t *)&v4->sin_addr.s_addr;
|
||||
addr.value.as_typed_data.values = (uint8_t *)&v4->sin_addr.s_addr;
|
||||
}
|
||||
|
||||
Dart_CObject *list[6]{&sockfd, &command, &method, &major, &minor, &addr};
|
||||
|
@ -151,7 +151,7 @@ int send_oncomplete(http_parser *parser, int code)
|
|||
//void handleRequest(const std::shared_ptr<requestInfo> &rq)
|
||||
void handleRequest(requestInfo *rq)
|
||||
{
|
||||
size_t len = 80 * 1024, nparsed;
|
||||
size_t len = 100 * 1024, nparsed;
|
||||
char buf[len];
|
||||
ssize_t recved;
|
||||
memset(buf, 0, len);
|
||||
|
@ -163,15 +163,15 @@ void handleRequest(requestInfo *rq)
|
|||
http_parser_settings settings{};
|
||||
|
||||
settings.on_message_begin = [](http_parser *parser) {
|
||||
std::cout << "mb" << std::endl;
|
||||
//std::cout << "mb" << std::endl;
|
||||
return send_notification(parser, 0);
|
||||
};
|
||||
|
||||
settings.on_message_complete = [](http_parser *parser) {
|
||||
std::cout << "mc" << std::endl;
|
||||
//std::cout << "mc" << std::endl;
|
||||
send_oncomplete(parser, 1);
|
||||
delete (requestInfo *)parser->data;
|
||||
std::cout << "deleted rq!" << std::endl;
|
||||
//std::cout << "deleted rq!" << std::endl;
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
@ -181,23 +181,23 @@ void handleRequest(requestInfo *rq)
|
|||
};
|
||||
|
||||
settings.on_header_field = [](http_parser *parser, const char *at, size_t length) {
|
||||
std::cout << "hf" << std::endl;
|
||||
//std::cout << "hf" << std::endl;
|
||||
return send_string(parser, (char *)at, length, 3);
|
||||
};
|
||||
|
||||
settings.on_header_value = [](http_parser *parser, const char *at, size_t length) {
|
||||
std::cout << "hv" << std::endl;
|
||||
//std::cout << "hv" << std::endl;
|
||||
return send_string(parser, (char *)at, length, 4);
|
||||
};
|
||||
|
||||
settings.on_body = [](http_parser *parser, const char *at, size_t length) {
|
||||
std::cout << "body" << std::endl;
|
||||
//std::cout << "body" << std::endl;
|
||||
return send_string(parser, (char *)at, length, 5, true);
|
||||
};
|
||||
|
||||
unsigned int isUpgrade = 0;
|
||||
|
||||
std::cout << "start" << std::endl;
|
||||
//std::cout << "start" << std::endl;
|
||||
while ((recved = recv(rq->sock, buf, len, 0)) > 0)
|
||||
{
|
||||
if (isUpgrade)
|
||||
|
@ -217,6 +217,7 @@ void handleRequest(requestInfo *rq)
|
|||
}
|
||||
else if (nparsed != recved)
|
||||
{
|
||||
//std::cout << "Hm what" << std::endl;
|
||||
close(rq->sock);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ dependencies:
|
|||
angel_framework: ^1.0.0
|
||||
build_native: ^0.0.9
|
||||
mock_request: ^1.0.0
|
||||
pooled_map: ^1.0.0
|
||||
#pooled_map: ^1.0.0
|
||||
uuid: ^1.0.0
|
||||
dev_dependencies:
|
||||
build_runner:
|
||||
|
|
Loading…
Reference in a new issue