NxWidgets: Fix a potential deadlock that can occur waiting for toolbard geometry data

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4709 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-05-07 15:05:07 +00:00
parent 424579fcba
commit b66dd903b6
4 changed files with 101 additions and 48 deletions

View File

@ -303,6 +303,16 @@ namespace NXWidgets
#endif
}
/**
* Wait for geometry data
*/
inline void waitGeoData(void)
{
takeGeoSem();
giveGeoSem();
}
/**
* Clear all mouse events
*/
@ -535,11 +545,11 @@ namespace NXWidgets
/**
* This event means that new mouse data is available for the window.
*
* @param pPos The (x,y) position of the mouse.
* @param pos The (x,y) position of the mouse.
* @param buttons See NX_MOUSE_* definitions.
*/
void newMouseEvent(FAR const struct nxgl_point_s *pPos, uint8_t buttons);
void newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons);
/**
* This event means that keyboard/keypad data is available for the window.
@ -570,71 +580,93 @@ namespace NXWidgets
}
/**
* Get the window bounding box in physical display coordinated.
* Get the window bounding box in physical display coordinated. This
* method may need to wait until geometry data is available.
*
* @return This function returns the window handle.
*/
inline CRect getWindowBoundingBox(void)
{
takeGeoSem();
CRect rect(&m_bounds);
giveGeoSem();
return rect;
waitGeoData();
return CRect(&m_bounds);
}
inline void getWindowBoundingBox(FAR struct nxgl_rect_s *bounds)
{
waitGeoData();
nxgl_rectcopy(bounds, &m_bounds);
}
/**
* Get the position of the window (as reported by the last NX callback).
* Get the position of the window (as reported by the last NX callback). This
* method may need to wait until geometry data is available.
*
* @return The position.
*/
inline bool getWindowPosition(FAR struct nxgl_point_s *pPos)
inline bool getWindowPosition(FAR struct nxgl_point_s *pos)
{
takeGeoSem();
pPos->x = m_pos.x;
pPos->x = m_pos.y;
giveGeoSem();
waitGeoData();
pos->x = m_pos.x;
pos->x = m_pos.y;
return true;
}
/**
* Get the size of the window (as reported by the last NX callback).
* Get the size of the window (as reported by the last NX callback). This
* method may need to wait until geometry data is available.
*
* @return The size.
*/
inline bool getWindowSize(FAR struct nxgl_size_s *pSize)
inline bool getWindowSize(FAR struct nxgl_size_s *size)
{
takeGeoSem();
pSize->h = m_size.h;
pSize->w = m_size.w;
giveGeoSem();
waitGeoData();
size->h = m_size.h;
size->w = m_size.w;
return true;
}
/**
* Get the width of the window (as reported by the last NX callback).
* Get the width of the window (as reported by the last NX callback). This
* method may need to wait until geometry data is available.
*
* @return The size.
*/
inline nxgl_coord_t getWindowWidth(void)
{
waitGeoData();
return m_size.w;
}
/**
* Get the height of the window (as reported by the last NX callback).
* Get the height of the window (as reported by the last NX callback). This
* method may need to wait until geometry data is available.
*
* @return The size.
*/
inline nxgl_coord_t getWindowHeight(void)
{
waitGeoData();
return m_size.h;
}
/**
* Set the size of the window. This is normally reported by an NX callback. But
* the toolbar widget control does not get NX callbacks and has to get the
* window size throught this method. This method should not be called by user
* code
*
* @param hWindow The window handle that should be used to communicate
* with the window
* @param bounds. The size of the underlying window.
*/
void setWindowBounds(NXHANDLE hWindow, FAR const struct nxgl_rect_s *bounds);
/**
* The creation sequence is:
*

View File

@ -178,6 +178,12 @@ CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height)
delete widgetControl;
return (CNxToolbar *)0;
}
// Provide parent widget control information to new widget control instance
struct nxgl_rect_s bounds;
m_widgetControl->getWindowBoundingBox(&bounds);
widgetControl->setWindowBounds(m_widgetControl->getWindowHandle(), &bounds);
}
return m_toolbar;

View File

@ -400,30 +400,18 @@ void CWidgetControl::setFocusedWidget(CNxWidget *widget)
}
/**
* This event is called from CCallback instance to provide
* notifications of certain NX-server related events. This event,
* in particular, will occur when the position or size of the underlying
* window occurs.
* Set the size of the window. This is normally reported by an NX callback. But
* the toolbar widget control does not get NX callbacks and has to get the
* window size throught this method. This method should not be called by user
* code
*
* @param hWindow The window handle that should be used to communicate
* with the window
* @param pos The position of the window in the physical device space.
* @param size The size of the window.
* @param bounds The size of the underlying display (pixels x rows)
* @param bounds. The size of the underlying window.
*/
void CWidgetControl::geometryEvent(NXHANDLE hWindow,
const struct nxgl_size_s *size,
const struct nxgl_point_s *pos,
const struct nxgl_rect_s *bounds)
void CWidgetControl::setWindowBounds(NXHANDLE hWindow, FAR const struct nxgl_rect_s *bounds)
{
// Save positional data that may change dynamically
m_pos.x = pos->x;
m_pos.y = pos->y;
m_size.h = size->h;
m_size.w = size->w;
// The first callback is important. This is the handshake that proves
// that we are truly communicating with the servier. This is also
// a critical point because this is when we know the physical
@ -445,6 +433,33 @@ void CWidgetControl::geometryEvent(NXHANDLE hWindow,
}
}
/**
* This event is called from CCallback instance to provide
* notifications of certain NX-server related events. This event,
* in particular, will occur when the position or size of the underlying
* window occurs.
*
* @param hWindow The window handle that should be used to communicate
* with the window
* @param pos The position of the window in the physical device space.
* @param size The size of the window.
* @param bounds The size of the underlying display (pixels x rows)
*/
void CWidgetControl::geometryEvent(NXHANDLE hWindow,
FAR const struct nxgl_size_s *size,
FAR const struct nxgl_point_s *pos,
FAR const struct nxgl_rect_s *bounds)
{
// Save positional data that may change dynamically
m_pos.x = pos->x;
m_pos.y = pos->y;
m_size.h = size->h;
m_size.w = size->w;
setWindowBounds(hWindow, bounds);
}
/**
* This event is called from CCallback instance to provide
* notifications of certain NX-server related events. This event,
@ -467,16 +482,16 @@ void CWidgetControl::redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more
* certain NX-server related events. This event, in particular, means that
* new mouse data is available for the window.
*
* @param pPos The (x,y) position of the mouse.
* @param pos The (x,y) position of the mouse.
* @param buttons See NX_MOUSE_* definitions.
*/
void CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pPos, uint8_t buttons)
void CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons)
{
// Save the mouse X/Y position
m_mouse.x = pPos->x;
m_mouse.y = pPos->y;
m_mouse.x = pos->x;
m_mouse.y = pos->y;
// Update button press states

View File

@ -1341,15 +1341,15 @@ int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
memset(&data, 0, sizeof(data));
sin = (FAR struct sockaddr_in *)&data.addr;
sin->sin_family = AF_INET;
sin->sin_port = htons(NFS_PORT);
sin->sin_addr = inaddr;
sin = (FAR struct sockaddr_in *)&data.addr;
sin->sin_family = AF_INET;
sin->sin_port = htons(NFS_PORT);
sin->sin_addr = inaddr;
data.addrlen = sizeof(struct sockaddr_in);
data.version = NFS_ARGSVERSION;
data.proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
data.sotype = (tcp) ? SOCK_STREAM : SOCK_DGRAM;
data.addrlen = sizeof(struct sockaddr_in);
data.flags = NFSMNT_NFSV3;
data.retrans = 3;
data.acregmin = 3;