app_server doesn't hang anymore when an application exits in an unclean way. Got rid of the kill_thread in ServerApp's destructor. Small refactoring. Added a TODO item.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12578 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -608,15 +608,6 @@ void AppServer::DispatchMessage(int32 code, BPortLink &msg)
|
|||||||
srvapp=(ServerApp *)fAppList->RemoveItem(i);
|
srvapp=(ServerApp *)fAppList->RemoveItem(i);
|
||||||
if(srvapp)
|
if(srvapp)
|
||||||
{
|
{
|
||||||
status_t temp;
|
|
||||||
// TODO: This call never returns, thus screwing the
|
|
||||||
// app server completely: it's easy to test:
|
|
||||||
// run any test app which creates a window, quit
|
|
||||||
// the application clicking on the window's "close" button,
|
|
||||||
// and try to launch the application again. It won't start.
|
|
||||||
// Anyway, this should be moved to ~ServerApp() (which has already
|
|
||||||
// a "kill_thread()" call, btw).
|
|
||||||
wait_for_thread(srvapp_id, &temp);
|
|
||||||
delete srvapp;
|
delete srvapp;
|
||||||
srvapp= NULL;
|
srvapp= NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,8 @@
|
|||||||
*/
|
*/
|
||||||
ServerApp::ServerApp(port_id sendport, port_id rcvport, port_id clientLooperPort,
|
ServerApp::ServerApp(port_id sendport, port_id rcvport, port_id clientLooperPort,
|
||||||
team_id clientTeamID, int32 handlerID, char *signature)
|
team_id clientTeamID, int32 handlerID, char *signature)
|
||||||
|
:
|
||||||
|
fQuitting(false)
|
||||||
{
|
{
|
||||||
// it will be of *very* musch use in correct window order
|
// it will be of *very* musch use in correct window order
|
||||||
fClientTeamID = clientTeamID;
|
fClientTeamID = clientTeamID;
|
||||||
@@ -140,33 +142,23 @@ ServerApp::ServerApp(port_id sendport, port_id rcvport, port_id clientLooperPort
|
|||||||
ServerApp::~ServerApp(void)
|
ServerApp::~ServerApp(void)
|
||||||
{
|
{
|
||||||
STRACE(("*ServerApp %s:~ServerApp()\n",fSignature.String()));
|
STRACE(("*ServerApp %s:~ServerApp()\n",fSignature.String()));
|
||||||
int32 i;
|
|
||||||
|
|
||||||
ServerBitmap *tempbmp;
|
fQuitting = true;
|
||||||
for(i=0;i<fBitmapList->CountItems();i++)
|
|
||||||
{
|
for (int32 i = 0; i< fBitmapList->CountItems(); i++)
|
||||||
tempbmp=(ServerBitmap*)fBitmapList->ItemAt(i);
|
delete static_cast<ServerBitmap *>(fBitmapList->ItemAt(i));
|
||||||
if(tempbmp)
|
|
||||||
delete tempbmp;
|
|
||||||
}
|
|
||||||
fBitmapList->MakeEmpty();
|
fBitmapList->MakeEmpty();
|
||||||
delete fBitmapList;
|
delete fBitmapList;
|
||||||
|
|
||||||
ServerPicture *temppic;
|
for (int32 i = 0; i < fPictureList->CountItems(); i++)
|
||||||
for(i=0;i<fPictureList->CountItems();i++)
|
delete static_cast<ServerPicture *>(fPictureList->ItemAt(i));
|
||||||
{
|
|
||||||
temppic=(ServerPicture*)fPictureList->ItemAt(i);
|
|
||||||
if(temppic)
|
|
||||||
delete temppic;
|
|
||||||
}
|
|
||||||
fPictureList->MakeEmpty();
|
fPictureList->MakeEmpty();
|
||||||
delete fPictureList;
|
delete fPictureList;
|
||||||
|
|
||||||
delete fMsgReader;
|
delete fMsgReader;
|
||||||
fMsgReader=NULL;
|
|
||||||
|
|
||||||
delete fMsgSender;
|
delete fMsgSender;
|
||||||
fMsgSender=NULL;
|
|
||||||
|
|
||||||
// This shouldn't be necessary -- all cursors owned by the app
|
// This shouldn't be necessary -- all cursors owned by the app
|
||||||
// should be cleaned up by RemoveAppCursors
|
// should be cleaned up by RemoveAppCursors
|
||||||
@@ -181,12 +173,21 @@ ServerApp::~ServerApp(void)
|
|||||||
|
|
||||||
STRACE(("#ServerApp %s:~ServerApp()\n",fSignature.String()));
|
STRACE(("#ServerApp %s:~ServerApp()\n",fSignature.String()));
|
||||||
|
|
||||||
|
// TODO: Is this the right place for this ?
|
||||||
|
// From what I've understood, this is the port created by
|
||||||
|
// the BApplication (?), but if I delete it in there, GetNextMessage()
|
||||||
|
// in the MonitorApp thread never returns. Cleanup.
|
||||||
|
delete_port(fMessagePort);
|
||||||
|
|
||||||
// Kill the monitor thread if it exists
|
// Kill the monitor thread if it exists
|
||||||
thread_info info;
|
thread_info info;
|
||||||
if(get_thread_info(fMonitorThreadID,&info)==B_OK)
|
status_t dummyStatus;
|
||||||
kill_thread(fMonitorThreadID);
|
if (get_thread_info(fMonitorThreadID, &info) == B_OK)
|
||||||
|
wait_for_thread(fMonitorThreadID, &dummyStatus);
|
||||||
|
|
||||||
delete fSharedMem;
|
delete fSharedMem;
|
||||||
|
|
||||||
|
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", fSignature.String()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -304,17 +305,18 @@ int32 ServerApp::MonitorApp(void *data)
|
|||||||
ServerApp *app = (ServerApp *)data;
|
ServerApp *app = (ServerApp *)data;
|
||||||
LinkMsgReader msgqueue(app->fMessagePort);
|
LinkMsgReader msgqueue(app->fMessagePort);
|
||||||
|
|
||||||
bool quitting = false;
|
|
||||||
int32 code;
|
int32 code;
|
||||||
status_t err = B_OK;
|
status_t err = B_OK;
|
||||||
|
|
||||||
while(!quitting)
|
while(!app->fQuitting)
|
||||||
{
|
{
|
||||||
STRACE(("info: ServerApp::MonitorApp listening on port %ld.\n", app->fMessagePort));
|
STRACE(("info: ServerApp::MonitorApp listening on port %ld.\n", app->fMessagePort));
|
||||||
// err = msgqueue.GetNextReply(&code);
|
// err = msgqueue.GetNextReply(&code);
|
||||||
err = msgqueue.GetNextMessage(&code);
|
err = msgqueue.GetNextMessage(&code);
|
||||||
if (err < B_OK)
|
if (err < B_OK) {
|
||||||
|
STRACE(("ServerApp::MonitorApp(): GetNextMessage returned %s\n", strerror(err)));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch(code)
|
switch(code)
|
||||||
{
|
{
|
||||||
@@ -390,13 +392,10 @@ int32 ServerApp::MonitorApp(void *data)
|
|||||||
{
|
{
|
||||||
STRACE(("ServerApp %s: B_QUIT_REQUESTED\n",app->fSignature.String()));
|
STRACE(("ServerApp %s: B_QUIT_REQUESTED\n",app->fSignature.String()));
|
||||||
// Our BApplication sent us this message when it quit.
|
// Our BApplication sent us this message when it quit.
|
||||||
// We need to ask the app_server to delete our monitor
|
// We need to ask the app_server to delete ourself.
|
||||||
// ADI: No! This is a bad solution. A thead should continue its
|
app->fQuitting = true;
|
||||||
// execution until its exit point, and this can *very* easily be done
|
|
||||||
quitting=true;
|
port_id serverport = find_port(SERVER_PORT_NAME);
|
||||||
// see... no need to ask the main thread to kill us.
|
|
||||||
// still... it will delete this ServerApp object.
|
|
||||||
port_id serverport = find_port(SERVER_PORT_NAME);
|
|
||||||
if(serverport == B_NAME_NOT_FOUND){
|
if(serverport == B_NAME_NOT_FOUND){
|
||||||
printf("PANIC: ServerApp %s could not find the app_server port!\n",app->fSignature.String());
|
printf("PANIC: ServerApp %s could not find the app_server port!\n",app->fSignature.String());
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
|
|
||||||
FMWList fAppFMWList;
|
FMWList fAppFMWList;
|
||||||
const char * Title() const { return fSignature.String(); }
|
const char * Title() const { return fSignature.String(); }
|
||||||
protected:
|
private:
|
||||||
friend class AppServer;
|
friend class AppServer;
|
||||||
friend class ServerWindow;
|
friend class ServerWindow;
|
||||||
|
|
||||||
@@ -108,6 +108,8 @@ protected:
|
|||||||
bool fIsActive;
|
bool fIsActive;
|
||||||
int32 fHandlerToken;
|
int32 fHandlerToken;
|
||||||
AreaPool *fSharedMem;
|
AreaPool *fSharedMem;
|
||||||
|
|
||||||
|
bool fQuitting;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user