Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

ISAPI(dll) разделение общих ресурсов в копиях dll [D7, WinXP]


piople ©   (2006-03-20 14:35:00) 

Доброго времени суток!
Вообщем разрабатываю сайт с использованием ISAPI, все замечательно, но столкнулся с такой проблемой - это общие ресурсы для всех копий dll, то есть, например, запросил пользователь некую страничку, берутся данные обрабатываются и в конечном итоге передаются клиенту... но, потом эти даннные по прежднему остаются в памяти, и при следующей запросе получается дублирование данных...

Детально:
некто запросил: babah.ru -> выполняется скрипт и результат помещается в некую переменную TMPVar-> результат скрипта отправлен пользователю...
следующий пользователь (либо паралельно с первым) выполняет запрос туда же: babah.ru -> выполняется скрипт и результат помещается в некую переменную и тут калапс, получается что в переменной хранятся старые данные и новые!!!-> пользователю уходят ненужные данные...

Казалось бы парень просто обнуляй переменную и все!!! Не хочет все равно... если допустим у меня цикл в моей dll который работает с TStringList и делает в него добавление данных (ADD) и тут же кто-то другой тоже далет запрос туда же (вернее хоть куда где использутеся мой TStringList) то он добавляет данные В ТОТ ЖЕ DLL!

Не знаю что делать... пытался копать в сторону:

const
 COINIT_MULTITHREADED = 0;
 COINIT_APARTMENTTHREADED = 2;

function CoInitializeEx(pvReserved: pointer; coInit:
 Longint): HResult; stdcall;
Параметр pvReserved зарезервирован для будущего использования и должен быть всегда равен nil, а параметр coInit определяет модель потоков создаваемого апартамента. Он может принимать значения COINIT_APARTMENTTHREADED и COINIT_MULTITHREADED. В первом случае для потока создается однопоточный апартамент, причем каждый поток может иметь, а может и не иметь свой апартамент. Во втором случае, если в текущем процессе еще не создан многопоточный апартамент, он создается. Если же многопоточный апартамент уже создан другим потоком, текущий поток подключается к готовому апартаменту. Другими словами, каждый процесс может иметь только один многопоточный апартамент. Вышеописанная функция возвращает значение S_OK в случае успешного создания апартамента. Каждому вызову CoInitializeEx должен соответствовать вызов CoUninitialize. То есть, если вы работаете с СОМ в приложении, функция CoInitializeEx должна быть вызвана до первого вызова функций СОМ, а CoUninitialize должна быть вызвана по завершении работы приложения. По завершении работы с СОМ (или перед завершением работы) поток должен уничтожить апартамент путем вызова процедуры CoUninitialize. Библиотека VCL выполняет автоматическую инициализацию СОМ при использовании модуля ComObj, и по умолчанию создается однопоточный апартамент. Если вам в приложении необходима другая модель потоков, следует внести исправления в файл проекта *.dpr, установив флаг инициализации СОМ до оператора Application.Initialize:

program Project1;
uses
 Forms, ComObj, ActiveX,
 Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
begin
 CoInitFlags := COINIT_MULTITHREADED;
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end;

к сожалению ничего не нашел...


Сергей М.   (2006-03-22 12:33:00) [1]


> WondeRu ©   (22.03.06 12:13) [17]


Потому что память под эту указательную переменную действительно выделяется в TLS текущего потока, а вот память под объект, на который впоследствии будет указывать эта переменная, выделяется уже не в TLS, а в куче.


WondeRu   (2006-03-22 12:13:00) [2]

Сергей М. ©   (22.03.06 12:12) [16]
SL: TStringList; // SL по сути и есть Pointer


сам же написал... почему, Сергей, это другое?


Сергей М.   (2006-03-22 12:12:00) [3]


> WondeRu ©   (22.03.06 11:50) [15]


Это несколько из другой оперы.

Убедись, что следующий код успешно работает:



threadvar
 SL: TStringList; // SL по сути и есть Pointer

type

 TMyThread = class(TThread)
 private
   FNum: Integer;
   FList: TStrings;
   procedure ShowList;
 protected
   procedure Execute; override;
   constructor Create(ThreadNum: Integer);
 end;

{ TMyThread }

constructor TMyThread.Create(ThreadNum: Integer);
begin
 FNum := ThreadNum;
 inherited Create(False);
end;

procedure TMyThread.Execute;
var
 i: Integer;
begin
 FreeOnTerminate := True;
 FList := TStringList.Create;
 SL:= TStringList.Create;
 for i:= FNum to FNum + 50 do
   SL.Add(IntToStr(i));
 FList.Assign(SL);
 Synchronize(ShowList);
 SL.Free;
 FList.Free;
end;

procedure TMyThread.ShowList;
var
 i: Integer;
begin
 for i:= 0 to FList.Count - 1 do
   Form1.Memo1.Lines.Add('ThreadNum = ' + IntToStr(FNum) + ' StringList[' + IntToStr(i) + '] = ' + FList[i]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 TMyThread.Create(1);
 TMyThread.Create(2);
end;


WondeRu   (2006-03-22 11:50:00) [4]

The threadvar section can only be used for global variables. Pointer and Function variables can't be thread variables.Types that use copy-on-write semantics, such as long strings don't work as thread variables either.


Сергей М.   (2006-03-22 10:59:00) [5]

threadvar
 Myvar: TStrings;

В событии BeforeDispatch:
 Myvar := TStringsList.Create;

В событии AfterDispatch:
 FreeAndNil(Myvar);


Сергей М.   (2006-03-22 10:50:00) [6]


> piople ©   (22.03.06 09:40) [12]


Все равно мне не понятно, почему вариант с глобальной threadvar-переменной не проходит .. Обязан проходить !


piople   (2006-03-22 09:40:00) [7]

К сожалению данные метод не реализуем в моей функции, так как я еще использую TPageProducer и у него свои процедуры/функции использующие те же стринглисты... :(


Сергей М.   (2006-03-21 12:50:00) [8]

см. событие TWebActionItem.OnAction

в его обработчике :

var TMPVar: TStringList;
begin
 TMPVar := TStringList.Create;
 try
   ... обрабатываешь акцию
 finally
   TMPVar.Free;
 end;
end;


piople   (2006-03-21 12:31:00) [9]

Создал...
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
....
news := TStringList.create; //Новостная лента
MainS := TStringList.Create; //Тело форума
Top10 := TStringList.Create; //10 последних сообщений
...
end;


Убил...
procedure TWebModule1.WebModuleDestroy(Sender: TObject);
begin
news.Free;
MainS.Free;
Top10.Free;
end;


Сергей М.   (2006-03-21 11:31:00) [10]

А где конструируешь-разрушаешь эттот объект ?


piople   (2006-03-21 11:14:00) [11]


> unit main;
>
> interface
>
> uses
>   SysUtils, Classes, HTTPApp, DB, ADODB, HTTPProd, DBWeb,
>  DBBdeWeb, StrUtils, windows,
>   mshtml, activex, OleCtrls, SHDocVw, variants, StdCtrls,
>  Math;
>
> type
>   TWebModule1 = class(TWebModule)
>     Tmpl: TPageProducer;
>     Query: TADOQuery;
>     DQuery: TADOQuery;
>     ADOConnection: TADOConnection;
>     ADOCommand: TADOCommand;
>
>      { Private declarations }
>   public
>
>     { Public declarations }
>   end;
>
> var
>   WebModule1: TWebModule1;
>     MainS, news, Top10     : TStringList; ВОТ ТУТ :)
>
> implementation
>
> uses Dialogs, DateUtils;
>
> {$R *.dfm}


Сергей М.   (2006-03-21 09:36:00) [12]


> piople ©   (21.03.06 09:32) [6]


> объявлен в общем VAR


Гдеобъявлена-то ?

Статическая это переменная или локальная ?


piople   (2006-03-21 09:32:00) [13]

TMPVar это мой TStringList объявлен в общем VAR...


Сергей М.   (2006-03-21 08:49:00) [14]

Ну где у тебя эта самая TMPVar объявлена ?


piople   (2006-03-21 05:38:00) [15]

хе... думаю многовато будет...
Что именно мне надо представить? Это обычный ISAPI...


Сергей М.   (2006-03-20 15:56:00) [16]

Приводи код


piople   (2006-03-20 15:16:00) [17]

К сожалению результат тот же...


Сергей М.   (2006-03-20 14:58:00) [18]


> в некую переменную TMPVar


library MyISAPIlib;
...

threadvar
 TMPVar: SomeType;

begin
..
  IsMultiThread := True;
..
end.


Наверх

Титульная страница Поиск, карта сайта Написать письмо