Fixed EXC_BAD_ACCESS

This commit is contained in:
Tobe O 2018-07-10 10:06:51 -04:00
parent 311dede079
commit 2409e06e6a
10 changed files with 75 additions and 71 deletions

View file

@ -2,7 +2,13 @@ CXX=clang
HTTP_PARSER=.dart_tool/build_native/third_party/angel_wings.http_parser HTTP_PARSER=.dart_tool/build_native/third_party/angel_wings.http_parser
CXX_INCLUDES=-I$(HTTP_PARSER) -I$(DART_SDK)/include 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: clean:
find lib -name "*.a" -delete find lib -name "*.a" -delete
@ -12,6 +18,9 @@ clean:
debug: debug:
$(MAKE) lib/src/libwings.dylib CXXFLAGS="-g -DDEBUG=1" $(MAKE) lib/src/libwings.dylib CXXFLAGS="-g -DDEBUG=1"
macos:
$(MAKE) lib/src/libwings.dylib
example: debug example: debug
lldb -o "target create dart" \ lldb -o "target create dart" \
-o "process launch --stop-at-entry example/main.dart" \ -o "process launch --stop-at-entry example/main.dart" \

View file

@ -5,7 +5,6 @@ import 'package:angel_framework/angel_framework.dart';
import 'package:angel_wings/angel_wings.dart'; import 'package:angel_wings/angel_wings.dart';
main() async { main() async {
if (false)
for (int i = 1; i < Platform.numberOfProcessors; i++) { for (int i = 1; i < Platform.numberOfProcessors; i++) {
var onError = new ReceivePort(); var onError = new ReceivePort();
Isolate.spawn(isolateMain, i, onError: onError.sendPort); Isolate.spawn(isolateMain, i, onError: onError.sendPort);
@ -18,7 +17,7 @@ main() async {
void isolateMain(int id) { void isolateMain(int id) {
var app = new Angel(); 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; var old = app.errorHandler;
app.errorHandler = (e, req, res) { app.errorHandler = (e, req, res) {

View file

@ -13,7 +13,7 @@ import 'package:http_parser/http_parser.dart';
import 'package:json_god/json_god.dart' as god; import 'package:json_god/json_god.dart' as god;
import 'package:mock_request/mock_request.dart'; import 'package:mock_request/mock_request.dart';
import 'package:pool/pool.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:stack_trace/stack_trace.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';

View file

@ -34,12 +34,11 @@ void wings_BindSocket(Dart_NativeArguments arguments)
std::string addressStringInstance(addressString); std::string addressStringInstance(addressString);
std::lock_guard<std::mutex> lock(serverInfoVectorMutex); std::lock_guard<std::mutex> lock(serverInfoVectorMutex);
#if __APPLE__
if (false)
#else
if (shared) if (shared)
#endif
{ {
#if __APPLE__
#else
for (unsigned long i = 0; i < serverInfoVector.size(); i++) for (unsigned long i = 0; i < serverInfoVector.size(); i++)
{ {
WingsServerInfo *server_info = serverInfoVector.at(i); WingsServerInfo *server_info = serverInfoVector.at(i);
@ -50,6 +49,7 @@ void wings_BindSocket(Dart_NativeArguments arguments)
break; break;
} }
} }
#endif
} }
if (existingIndex > -1) if (existingIndex > -1)

View file

@ -1,6 +1,6 @@
#include <dart_native_api.h> #include <dart_native_api.h>
#include <thread> #include <thread>
#include <iostream> //#include <iostream>
#include <cstdio> #include <cstdio>
#include "wings.h" #include "wings.h"
#include "wings_thread.h" #include "wings_thread.h"
@ -56,9 +56,9 @@ void handleMessage(Dart_Port destPortId, Dart_CObject *message)
else else
{ {
// This is either a send or close message. // 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]); 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) 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) if (msg->type == Dart_CObject_kExternalTypedData)
{ {
std::cout << "ext typed data" << std::endl; //std::cout << "ext typed data" << std::endl;
printf("Length: %ld\n", msg->value.as_external_typed_data.length); //printf("Length: %ld\n", msg->value.as_external_typed_data.length);
std::cout << "ptr: " << msg->value.as_typed_data.values << std::endl; //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); 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) else if (msg->type == Dart_CObject_kTypedData)
{ {
std::cout << "regular typed data" << std::endl; //std::cout << "regular typed data" << std::endl;
printf("Length: %ld\n", msg->value.as_typed_data.length); //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); write(sockfd, msg->value.as_typed_data.values, (size_t)msg->value.as_typed_data.length);
} }
else else
{ {
std::cout << "unknown type: " << ((Dart_CObject_Type) msg->type) << std::endl; //std::cout << "unknown type: " << ((Dart_CObject_Type) msg->type) << std::endl;
} }
} }
else else
{ {
std::cout << "null msg!!!" << std::endl; //std::cout << "null msg!!!" << std::endl;
} }
} }
else else
{ {
printf("Close!\n"); //printf("Close!\n");
close(sockfd); close(sockfd);
} }
} }

View file

@ -1,6 +1,3 @@
#ifdef DEBUG
#include "dart_debug.h"
#endif
#include "wings.h" #include "wings.h"
void wings_CloseSocket(Dart_NativeArguments arguments) void wings_CloseSocket(Dart_NativeArguments arguments)
@ -20,9 +17,6 @@ void wings_Send(Dart_NativeArguments arguments)
void *dataBytes; void *dataBytes;
intptr_t dataLength; intptr_t dataLength;
#ifdef DEBUG
HandleError(Dart_Print(sockfdHandle));
#endif
HandleError(Dart_IntegerToUint64(sockfdHandle, &sockfd)); HandleError(Dart_IntegerToUint64(sockfdHandle, &sockfd));
HandleError(Dart_TypedDataAcquireData(dataHandle, &dataType, &dataBytes, &dataLength)); HandleError(Dart_TypedDataAcquireData(dataHandle, &dataType, &dataBytes, &dataLength));
write((int)sockfd, dataBytes, (size_t)dataLength); write((int)sockfd, dataBytes, (size_t)dataLength);

View file

@ -89,12 +89,13 @@ class AngelWings {
static SendPort _startHttpListener() native "StartHttpListener"; 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) { void _send(int sockfd, Uint8List data) {
// _pool.withResource(() { // _pool.withResource(() {
print('Sending ${[sockfd, data]}'); print('Sending ${[sockfd, data]}');
@ -113,7 +114,7 @@ class AngelWings {
} }
//}); //});
//_pool.withResource(() => __closeSocket(sockfd)); //_pool.withResource(() => __closeSocket(sockfd));
} }*/
AngelWings(this.app, {this.shared: false, this.useZone: true}) { AngelWings(this.app, {this.shared: false, this.useZone: true}) {
_recv.handler = _handleMessage; _recv.handler = _handleMessage;
@ -164,7 +165,7 @@ class AngelWings {
} }
void _handleMessage(x) { void _handleMessage(x) {
print('INPUT: $x'); //print('INPUT: $x');
if (x is String) { if (x is String) {
close(); close();
throw new StateError(x); throw new StateError(x);
@ -177,11 +178,11 @@ class AngelWings {
switch (command) { switch (command) {
case messageBegin: case messageBegin:
print('BEGIN $sockfd'); //print('BEGIN $sockfd');
_staging[sockfd] = new WingsRequestContext._(this, sockfd, app); _staging[sockfd] = new WingsRequestContext._(this, sockfd, app);
break; break;
case messageComplete: case messageComplete:
print('$sockfd in $_staging???'); //print('$sockfd in $_staging???');
var rq = _staging.remove(sockfd); var rq = _staging.remove(sockfd);
if (rq != null) { if (rq != null) {
rq._method = methodToString(x[2] as int); rq._method = methodToString(x[2] as int);
@ -218,13 +219,13 @@ class AngelWings {
} }
Future _handleRequest(WingsRequestContext req) { Future _handleRequest(WingsRequestContext req) {
print('req: $req'); //print('req: $req');
if (req == null) return new Future.value(); if (req == null) return new Future.value();
var res = new WingsResponseContext._(req) var res = new WingsResponseContext._(req)
..app = app ..app = app
..serializer = (app.serializer ?? god.serialize) ..serializer = (app.serializer ?? god.serialize)
..encoders.addAll(app.encoders); ..encoders.addAll(app.encoders);
print('Handling fd: ${req._sockfd}'); //print('Handling fd: ${req._sockfd}');
handle() { handle() {
var path = req.path; var path = req.path;
@ -257,7 +258,7 @@ class AngelWings {
Future<bool> Function() runPipeline; Future<bool> Function() runPipeline;
print('Pipeline: $pipeline'); //print('Pipeline: $pipeline');
for (var handler in pipeline) { for (var handler in pipeline) {
if (handler == null) break; if (handler == null) break;
@ -316,7 +317,7 @@ class AngelWings {
return handleAngelHttpException(e, trace, req, res); return handleAngelHttpException(e, trace, req, res);
}).catchError((e, StackTrace st) { }).catchError((e, StackTrace st) {
var trace = new Trace.from(st ?? StackTrace.current).terse; 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, // Ideally, we won't be in a position where an absolutely fatal error occurs,
// but if so, we'll need to log it. // but if so, we'll need to log it.
if (app.logger != null) { if (app.logger != null) {
@ -354,7 +355,7 @@ class AngelWings {
b.writeln(); b.writeln();
_send(req._sockfd, _coerceUint8List(b.toString().codeUnits)); _send(req._sockfd, _coerceUint8List(b.toString().codeUnits));
_closeSocket(req); AngelWings._closeSocket(req._sockfd);
} finally { } finally {
return null; return null;
} }
@ -379,9 +380,9 @@ class AngelWings {
/// Sends a response. /// Sends a response.
Future sendResponse(WingsRequestContext req, WingsResponseContext res, Future sendResponse(WingsRequestContext req, WingsResponseContext res,
{bool ignoreFinalizers: false}) { {bool ignoreFinalizers: false}) {
print('Closing: ${req._sockfd}'); //print('Closing: ${req._sockfd}');
if (res.willCloseItself) return new Future.value(); if (res.willCloseItself) return new Future.value();
print('Not self-closing: ${req._sockfd}'); //print('Not self-closing: ${req._sockfd}');
Future finalizers = ignoreFinalizers == true Future finalizers = ignoreFinalizers == true
? new Future.value() ? new Future.value()
@ -399,7 +400,7 @@ class AngelWings {
//request.response.headers.chunkedTransferEncoding = res.chunked ?? true; //request.response.headers.chunkedTransferEncoding = res.chunked ?? true;
// TODO: Is there a need to support this? // TODO: Is there a need to support this?
print('Buffer: ${res.buffer}'); //print('Buffer: ${res.buffer}');
List<int> outputBuffer = res.buffer.toBytes(); List<int> outputBuffer = res.buffer.toBytes();
if (res.encoders.isNotEmpty) { if (res.encoders.isNotEmpty) {
@ -437,7 +438,7 @@ class AngelWings {
} }
} }
print('Create string buffer'); //print('Create string buffer');
var b = new StringBuffer(); var b = new StringBuffer();
b.writeln('HTTP/1.1 ${res.statusCode}'); b.writeln('HTTP/1.1 ${res.statusCode}');
@ -458,20 +459,20 @@ class AngelWings {
} }
b.writeln(); b.writeln();
print(b); //print(b);
var bb = new BytesBuilder(copy: false) var bb = new BytesBuilder(copy: false)
..add(b.toString().codeUnits) ..add(b.toString().codeUnits)
..add(outputBuffer); ..add(outputBuffer);
var buf = _coerceUint8List(bb.takeBytes()); var buf = _coerceUint8List(bb.takeBytes());
print('Output: $buf'); //print('Output: $buf');
return finalizers.then((_) { return finalizers.then((_) {
print('A'); //print('A');
_send(req._sockfd, buf); _send(req._sockfd, buf);
print('B'); //print('B');
_closeSocket(req); AngelWings._closeSocket(req._sockfd);
print('C'); //print('C');
if (req.injections.containsKey(PoolResource)) { if (req.injections.containsKey(PoolResource)) {
req.injections[PoolResource].release(); req.injections[PoolResource].release();

View file

@ -13,14 +13,14 @@ class WingsResponseContext extends ResponseContext {
if (_isClosed && !_useStream) if (_isClosed && !_useStream)
throw ResponseContext.closed(); throw ResponseContext.closed();
else if (_useStream) else if (_useStream)
_wings._send(correspondingRequest._sockfd, _coerceUint8List(data)); AngelWings._send(correspondingRequest._sockfd, _coerceUint8List(data));
else else
buffer.add(data); buffer.add(data);
} }
@override @override
Future close() { Future close() {
_wings._closeSocket(correspondingRequest); AngelWings._closeSocket(correspondingRequest._sockfd);
_isClosed = true; _isClosed = true;
_useStream = false; _useStream = false;
return super.close(); return super.close();
@ -77,7 +77,7 @@ class WingsResponseContext extends ResponseContext {
} }
return output.forEach(((data) => return output.forEach(((data) =>
_wings._send(correspondingRequest._sockfd, _coerceUint8List(data)))); AngelWings._send(correspondingRequest._sockfd, _coerceUint8List(data))));
} }
@override @override
@ -147,7 +147,7 @@ class WingsResponseContext extends ResponseContext {
b.writeln(); b.writeln();
_wings._send( AngelWings._send(
correspondingRequest._sockfd, _coerceUint8List(b.toString().codeUnits)); correspondingRequest._sockfd, _coerceUint8List(b.toString().codeUnits));
} }
} }

View file

@ -1,5 +1,5 @@
//#include <memory> //#include <memory>
#include <iostream> //#include <iostream>
#include <utility> #include <utility>
#include <dart_native_api.h> #include <dart_native_api.h>
#include "wings_thread.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 else
{ {
third.type = Dart_CObject_kExternalTypedData; third.type = Dart_CObject_kTypedData;
third.type = Dart_CObject_kExternalTypedData; third.type = Dart_CObject_kTypedData;
third.value.as_external_typed_data.type = Dart_TypedData_kUint8; third.value.as_typed_data.type = Dart_TypedData_kUint8;
third.value.as_external_typed_data.length = length; third.value.as_typed_data.length = length;
third.value.as_external_typed_data.data = (uint8_t *)str; third.value.as_typed_data.values = (uint8_t *)str;
} }
// Post the string back to Dart... // Post the string back to Dart...
@ -118,24 +118,24 @@ int send_oncomplete(http_parser *parser, int code)
Dart_CObject minor{}; Dart_CObject minor{};
Dart_CObject addr{}; Dart_CObject addr{};
sockfd.type = command.type = method.type = major.type = minor.type = Dart_CObject_kInt32; 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; sockfd.value.as_int32 = rq->sock;
command.value.as_int32 = code; command.value.as_int32 = code;
method.value.as_int32 = parser->method; method.value.as_int32 = parser->method;
major.value.as_int32 = parser->http_major; major.value.as_int32 = parser->http_major;
minor.value.as_int32 = parser->http_minor; minor.value.as_int32 = parser->http_minor;
addr.value.as_external_typed_data.type = Dart_TypedData_kUint8; addr.value.as_typed_data.type = Dart_TypedData_kUint8;
addr.value.as_external_typed_data.length = rq->addr_len; addr.value.as_typed_data.length = rq->addr_len;
if (rq->ipv6) if (rq->ipv6)
{ {
auto *v6 = (sockaddr_in6 *)&rq->addr; 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 else
{ {
auto *v4 = (sockaddr_in *)&rq->addr; 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}; 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(const std::shared_ptr<requestInfo> &rq)
void handleRequest(requestInfo *rq) void handleRequest(requestInfo *rq)
{ {
size_t len = 80 * 1024, nparsed; size_t len = 100 * 1024, nparsed;
char buf[len]; char buf[len];
ssize_t recved; ssize_t recved;
memset(buf, 0, len); memset(buf, 0, len);
@ -163,15 +163,15 @@ void handleRequest(requestInfo *rq)
http_parser_settings settings{}; http_parser_settings settings{};
settings.on_message_begin = [](http_parser *parser) { settings.on_message_begin = [](http_parser *parser) {
std::cout << "mb" << std::endl; //std::cout << "mb" << std::endl;
return send_notification(parser, 0); return send_notification(parser, 0);
}; };
settings.on_message_complete = [](http_parser *parser) { settings.on_message_complete = [](http_parser *parser) {
std::cout << "mc" << std::endl; //std::cout << "mc" << std::endl;
send_oncomplete(parser, 1); send_oncomplete(parser, 1);
delete (requestInfo *)parser->data; delete (requestInfo *)parser->data;
std::cout << "deleted rq!" << std::endl; //std::cout << "deleted rq!" << std::endl;
return 0; return 0;
}; };
@ -181,23 +181,23 @@ void handleRequest(requestInfo *rq)
}; };
settings.on_header_field = [](http_parser *parser, const char *at, size_t length) { 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); return send_string(parser, (char *)at, length, 3);
}; };
settings.on_header_value = [](http_parser *parser, const char *at, size_t length) { 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); return send_string(parser, (char *)at, length, 4);
}; };
settings.on_body = [](http_parser *parser, const char *at, size_t length) { 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); return send_string(parser, (char *)at, length, 5, true);
}; };
unsigned int isUpgrade = 0; unsigned int isUpgrade = 0;
std::cout << "start" << std::endl; //std::cout << "start" << std::endl;
while ((recved = recv(rq->sock, buf, len, 0)) > 0) while ((recved = recv(rq->sock, buf, len, 0)) > 0)
{ {
if (isUpgrade) if (isUpgrade)
@ -217,6 +217,7 @@ void handleRequest(requestInfo *rq)
} }
else if (nparsed != recved) else if (nparsed != recved)
{ {
//std::cout << "Hm what" << std::endl;
close(rq->sock); close(rq->sock);
return; return;
} }

View file

@ -3,7 +3,7 @@ dependencies:
angel_framework: ^1.0.0 angel_framework: ^1.0.0
build_native: ^0.0.9 build_native: ^0.0.9
mock_request: ^1.0.0 mock_request: ^1.0.0
pooled_map: ^1.0.0 #pooled_map: ^1.0.0
uuid: ^1.0.0 uuid: ^1.0.0
dev_dependencies: dev_dependencies:
build_runner: build_runner: