Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.05.29;
Скачать: CL | DM;

Вниз

Распределение памяти ( Зависает send() )   Найти похожие ветки 

 
aeore   (2009-10-12 17:06) [0]

Уже несколько часов сижу - не могу понять почему не работает. И так - в следующем коде, при выполнении функции send() компьютер зависает намертво. Сам код является частью процедуры Execute() потока. Задача кода - составить пакет из структуры TAUD_SESSION_DATA и звуковых данных по адресу
PWAVEHDR(Msg.lParam)^.dwBytesRecorded и послать его на сокет. Все данные есть, нужно только запихнуть их в буфер и послать. Отладчик тоже говорит, что все данные доступны и в буфер нормально добавляются. И так, код:

type
 PAUD_SESSION_DATA = ^TAUD_SESSION_DATA;
 TAUD_SESSION_DATA = packed record
   Msg: Byte;  
   Len: Word;
 end;
const
 AUD_AUDIO_DATA                                               = $08;
var
 buf: Pointer;
 _AUD_SESSION_DATA: TAUD_SESSION_DATA;
 Msg: TMsg;
 AudioSize: Cardinal;
 AudioData: PAnsiChar;
begin
 ... ... ... GetMessage(Msg, 0, 0, 0) ... ...
 ...
 AudioSize := PWAVEHDR(Msg.lParam)^.dwBytesRecorded;
 AudioData := PWAVEHDR(Msg.lParam)^.lpData;
 _AUD_SESSION_DATA.Msg := AUD_AUDIO_DATA;
 _AUD_SESSION_DATA.Len := AudioSize;
 GetMem(buf, SizeOf(TAUD_SESSION_DATA) + AudioSize);
 CopyMemory(buf, @_AUD_SESSION_DATA, SizeOf(TAUD_SESSION_DATA));
 CopyMemory(Pointer(Integer(buf) + SizeOf(TAUD_SESSION_DATA)), AudioData, AudioSize);
 send(fSocket, buf^,  SizeOf(TAUD_SESSION_DATA) + AudioSize, 0);
 FreeMem(buf);
 ...
end;

В чем может быть проблема?


 
Сергей М. ©   (2009-10-12 17:20) [1]


> Отладчик тоже говорит, что все данные доступны и в буфер
> нормально добавляются


А что тот же отладчик говорит по поводу собственно исполнения ф-ции send() ?


 
Сергей М. ©   (2009-10-12 17:24) [2]


> компьютер зависает намертво


Свежо предание, но верится с трудом)

С чего бы ему, компьютеру, зависнуть, да еще и намертво ?

Максимум что можно учудить при этом - вызвать у системы рвотный рефлекс, при котором она выплюнет твой процесс из списка существующих.


 
aeore   (2009-10-12 17:43) [3]

>А что тот же отладчик говорит по поводу собственно исполнения ф-ции send() ?

если ее выполнить по Ctrl + F7, то зависнет так же

>С чего бы ему, компьютеру, зависнуть, да еще и намертво ?

и тем не менее. Пробовал на двух компьютерах. Мышь шевелится с перерывами, больше ничего.


 
Сергей М. ©   (2009-10-12 17:50) [4]


> Мышь шевелится


Значит отнюдь не намертво, вопреки твоему утверждению)

Да и на нажатие Ctrl-Alt-Del наверняка есть нормальная реакция, т.е. ни о какой "висячей компьютерной смерти" речи идти не может, так ?


 
Сергей М. ©   (2009-10-12 17:56) [5]


> если ее выполнить по Ctrl + F7


Ctrl + F7, вообще-то, ничего не выполняет - эта комбинация для Evaluate/Modify, а не для Trace, не для Step и не для Run


 
aeore   (2009-10-12 18:32) [6]

нет, на ctrl+alt+del реакции нет, про Trace я уже не говорю

Я только что нашел еще кое-что - этот код не глючит сам по себе, а только если вызван из другого потока (вызов из vcl работает).

Если это из vcl, то работает
fAudioTX.State := TX_STATE_START_TX;
а если это же вызовет другой поток в Synchronize(), то опаньки.

procedure TAudioTX.Execute:
...
begin
...
 case fState of
       ....
       ....
       ....
     TX_STAT_ABORT: ;

     TX_STATE_START_TX:
       begin
         fStopTransmit := False;
         PeekMessage(Msg, 0, 0, 0, PM_REMOVE);
         OpenWave;
         Priority := tpTimeCritical;
         try
           while (not Terminated) and GetMessage(Msg, 0, 0, 0) and (not fStopTransmit) do
             case Msg.message of
               MM_WIM_OPEN:
                 begin
              ....
                 end;

               MM_WIM_DATA:
                 begin
           ....
                 end;
             end;
         finally
           CloseWave;
         end;
       end;
 end;

Сейчас попробую переделать и упростить архитектуру - если не заработает, запощу сюда более вменяемое описание, а то сейчас что бы показать все зависимости, нужно строк 500 привести.


 
Сергей М. ©   (2009-10-12 18:37) [7]


> Priority := tpTimeCritical;


Опаньки !!

Это нахрена ?!!

Ты сам-то понимаешь что ты при этом творишь ?


 
Сергей М. ©   (2009-10-12 18:41) [8]

When manipulating priorities, be very careful  to ensure that a high-priority thread does not consume all of the available CPU time. A thread with a base priority level above 11 interferes with the normal operation of the operating system. Using REALTIME_PRIORITY_CLASS may cause disk caches to not flush, hang the mouse, and so on.

Чему же тут удивляться ?)


 
aeore   (2009-10-12 18:42) [9]

c tpLower работает аналогично.

А такой высокий приоритет поставил, т.к. боялся что еще чего пропущу при большой посторонней загрузке (в потоке данные с микрофона читаются и передаются на сервер-роутер, откуда уходят на других клиентов)


 
aeore   (2009-10-12 18:44) [10]

кстати, при запуске из vcl никаких замираний не происходит - все работает чисто и аккуратно, хотя стоит tpTimeCritical. При этом это модернизация ранее работающего кода, где все так же (и так же совершенно не жрет проц). По Ctrl+Alt+Del загрузка проца 0%


 
aeore   (2009-10-12 18:45) [11]

Ну это ладно, тут можно и Normal поставить я думаю, ничего страшного не произойдет. Проблема же явно не в этом.


 
Сергей М. ©   (2009-10-12 18:55) [12]

Режим сокета, надо понимать, блокирующий ?


 
aeore   (2009-10-12 19:00) [13]

прием идет в отдельном потоке, не блокирующий (select: таймаут), что бы можно было завершить поток.

Я уже разработал более лаконичную архитектуру, завтра буду реализовывать и проверять.


 
Сергей М. ©   (2009-10-12 19:02) [14]

И вообще с какого боку здесь Synchronize ?
Что с чем ты пытаешься синхронизировать ?


 
Сергей М. ©   (2009-10-12 19:05) [15]


> не блокирующий


А где же тогда у тебя обязательный анализ результата вызова send() ?


> что бы можно было завершить поток


Поток можно завершить в любом режиме, использование неблок.режима для сей цели вовсе не обязательна.


 
aeore   (2009-10-16 09:48) [16]

Все, переписал код по новому и заработало)

>И вообще с какого боку здесь Synchronize

Когда приемный поток принимает пакет с запросом о входящей связи, он вызывает Synchronize что бы сообщить об этом факте vcl.

>А где же тогда у тебя обязательный анализ результата вызова send() ?

Не написал. Мне же необходимо было проверить работоспособность. а написать проверку всегда можно успеть.



Страницы: 1 вся ветка

Текущий архив: 2011.05.29;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.009 c
1-1255507938
defen
2009-10-14 12:12
2011.05.29
исключение для EDBEngineError


1-1255414815
Игорь
2009-10-13 10:20
2011.05.29
ConstrainedResize


2-1297940727
SIV5000
2011-02-17 14:05
2011.05.29
Загрузка файла разными потоками


2-1297928446
Andrey10
2011-02-17 10:40
2011.05.29
вопрос по бд


1-1255951017
kyn66
2009-10-19 15:16
2011.05.29
Поле Date в SQl запросе