[openrtm-users 00038] RtcRingBuffer::get_new_list()のデッドロック

稲村 渡 wataru_inamura @ ihi.co.jp
2005年 11月 22日 (火) 14:32:22 JST


稲村@IHIです。

バグ報告です。

InPortで、getNewList()メソッドを使うと、デッドロックします。
getNewList()メソッドは、RtcRingBufferのget_new_list()メソッド
を呼び出していますが、ここで、同じミューテックスを2重にロックしていました。

	inline std::vector<T> get_new_list()
	{
	  ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex); // <= ここでロック
	  std::vector<T> data;
	  int len(new_data_len()); // <= この中でもロック
	  data.resize(len);
	 …
	}


そこで、ロックを行なわないプライベートメソッドを用意し、
get_new_list()、new_data_len()から呼び出すように修正しました。

	inline std::vector<T> get_new_list()
	{
	  ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex); // <= ここでロック
	  
	  std::vector<T> data;
	  int len(new_data_len_no_guard()); // <= ロックしない
	  data.resize(len);
	 …
	}

	inline int new_data_len()
	{
	  ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex); // <= ここでロック
	  return new_data_len_no_guard(); // <= ロックしない
	}

private:
	inline int new_data_len_no_guard()
	{
	  int cnt(0);
	  for (int i(m_Newest);
		   m_Buffer[i].is_new() && cnt < m_Length;
		   ++cnt, --i < 0 ? (i = m_Length - 1) : 0)
		{;}
	  return cnt;
	}







openrtm-users メーリングリストの案内