Как правильно использовать метод Apache apr_pool_create_ex в Delphi XE? - PullRequest
1 голос
/ 25 марта 2011

Как правильно использовать метод Apache apr_pool_create_ex в Delphi XE?

Ранее я создавал модули Apache, но все они были обработчиками.Сейчас я работаю над разработкой поставщика услуг.Был создан скелетный модуль, и Apache вызывает мой метод обратного вызова child_init.В методе child_init я успешно вызываю ap_pool_create_ex * (возвращает APR_SUCCESS), но после выхода из вызова child_it я получаю нарушение прав доступа либо во время нереста (httpd.exe) третьего или четвертого рабочего потока (третий отображается в событии)журнал).

procedure provider_child_init(pchild: Papr_pool_t; s: Pserver_rec); cdecl;
var
  rv  : apr_status_t;
  mypool : Papr_pool_t;
begin
  rv := -1;
  rv := apr_pool_create_ex(@mypool,pchild,nil,nil);
end;

Сообщение AV:

«Проект C: \ Apache2.2 \ bin \ http.exe выдал слишком много последовательных исключений: 'нарушение прав доступа в 0x00000000: чтениеадреса 0x00000000 '.Процесс остановлен.Используйте Step или Run для продолжения ”

Журнал событий:

…
Thread Start: Thread ID: 5652. Process httpd.exe (4212)
Thread Start: Thread ID: 5132. Process httpd.exe (4212)
Thread Start: Thread ID: 5988. Process httpd.exe (4212) 

ПРИМЕЧАНИЕ. AV происходит в идентификаторе потока 5988, а 4212 - это процесс родительского httpd.exe.

  • Windows «libapr-1.dll» не содержит «apr_pool_create», поэтому я использую версию «_ex».Любая идея, почему отсутствует apr_pool_create?Я вижу, что apr_pool_create используется в других успешных модулях , хотя они записаны в 'C'.

OS : 64-битная ОС Windows 7 Enterprise

Apache : 2.2.17.0

IDE : Delphi XE

1 Ответ

2 голосов
/ 26 марта 2011

Ваш перевод функции правильный? Delphi XE Version Insight (плагин Subversion) объявляет его следующим образом:

type
  PAprPool = ^TAprPool;
  TAprPool = THandle;
  PAprAllocator = ^TAprAllocator;
  TAprAllocator = THandle;
  TAprAbortFunc = function(retcode: Integer): Integer; stdcall;

var
  apr_pool_create_ex: function(out newpool: PAprPool; parent: PAprPool; abort_fn: TAprAbortFunc;
    allocator: PAprAllocator): TAprStatus; stdcall;

Также проверьте, действительно ли ваш обратный вызов provider_child_init должен быть объявлен как cdecl, а не stdcall.

Кроме того, некоторые идеи, поскольку вы получаете нарушение доступа к нулевому указателю.Согласно исходному коду apr comment :

  • , если (как в вашем случае) вы передадите ему нулевой распределитель, будет использован распределитель родительского пула.Я предполагаю, что в случае, если родительский пул равен nil, распределитель не должен быть nil.
  • abort_fn будет вызван обратно, если пул не может выделить память.Вы передаете это ноль;возможно, пул пытается вызвать его, потому что он не может выделить память?
  • Я не думаю, что вы можете получить доступ к одному и тому же пулу из разных потоков.Возможно, вам придется создать отдельный пул для каждого потока.
...