Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> VariantCopy method is not threadsafe 
V
    Опции темы
voov
Дата 11.9.2008, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: нет
Всего: 8



При копировании VARIANT получаю ошибку Access violation reading location.

В мсдн пишут, что VariantCopy method is not threadsafe. Мое приложение действительно многопоточное.
Кроме того, скомпилированая дэбаг версия запущеная отладчиком студии, работает нормально, а запущеная вне студии получает исключение Access violation reading location.

В чем именно опасность метода VariantCopy в многопоточном приложении и как устранить такую опасность?
PM MAIL   Вверх
Andrey44
Дата 12.9.2008, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



voov, а может стоит попробовать memcpy или что-то в этом духе?


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
ama_kid
Дата 12.9.2008, 09:37 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 5
Всего: 95



Цитата(voov @  11.9.2008,  16:20 Найти цитируемый пост)
В чем именно опасность метода VariantCopy в многопоточном приложении
VariantCopy - это не-атомарная операция, требует несколько шагов для своего выполнения, как минимум:
1) variant-приемник должен освободить свои ресурсы перед приёмом
2) должно произвестись копирование из источника в приёмник.
В многопоточном приложении теоретически возможно такое, что в приёмник присвоятся новые данные\ресурсы между освобождением старых и присвоением новых при копировании.


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
voov
Дата 12.9.2008, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: нет
Всего: 8



Цитата(ama_kid @  12.9.2008,  09:37 Найти цитируемый пост)
В многопоточном приложении теоретически возможно такое, что в приёмник присвоятся новые данные\ресурсы между освобождением старых и присвоением новых при копировании. 

а как избежать такой ситуации? можно ли здесь както использовать CriticalSection или нужно по другому копировать?
PM MAIL   Вверх
voov
Дата 30.9.2008, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: нет
Всего: 8



Следующий код:
Код

ItemData::ItemData( VARIANT & src ){
    VARIANT dst;
    dst.vt = VT_EMPTY;
    HRESULT result = VariantCopy( &dst, &src);
                ....
}

запущеный отладчиком студии (F5) работает без ошибок. Если запустить приложение вне студии (exe-файл из проводника, например), идут ошибки.

Сделал так: запустил приложение вне студии, сделал Attach to process... из студии и вижу такую штуку:
1. ошибки возникают только в том случае, если src содержит массив, но не всякий раз. некоторые вызовы, где src - массив, проходят успешно.
2. в случае возникновения ошибки result (E_INVALIDARG) показывает, что "Параметр задан неверно.". При этом портится src. Вместо safearray of R4 = [3](5.0000000,5.0000000,5.0000000)  (до вызова VariantCopy), он показывает safearray of R4 = [0]()  (после вызова VariantCopy) и т.п.

Получается, что во время выполнения VariantCopy, портится источник данных. Но как, где и почему портится непонятно. src создается перед вызовом этим же потоком и удаляется только после выполнения вышеуказаного кода
Код

typedef struct ITEMSTATE    {
    VARIANT vDataValue;
} ITEMSTATE;

.....
    ITEMSTATE *itemState = NULL;
    DWORD noItems = (DWORD)items.GetCount();

    HRESULT    result = iSychIO->Read(noItems, &itemState);    // СОМ интерфейс
    if (FAILED(result)){
        throw ...
    } 

    for (unsigned i = 0; i < noItems; i++){
        ItemData * data = NULL;
        data = new ItemData(itemState[i].vDataValue);    // здесь вариант должен скопироваться
    }

    iMalloc->Free(itemState);     // вот только здесь должен портиться источник данных


Попробую копировать вручную, но энтузиазма нет как и нет уверености, что поможет. Может кто-то все-таки может подсказать что-то  дельное?
PM MAIL   Вверх
voov
Дата 30.9.2008, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: нет
Всего: 8



Вопрос снят.
Проблема была связана с освобождением памяти. Долго объяснять, скажу лишь, что ItemData это обертка для варианта, деструктор которой вызывает VariantClear. В одном месте я нашел лишний вызов VariantClear для данных из этой обертки. Из-за чего в деструкторе вызов VariantClear говорил что память заблокирована. 
После удаления лишнего вызова VariantClear ошибки прекратились.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1158 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.