The wonders of signals:
* Since the app_server launched the input_server, it would also get notified when the latter died via a signal - but LinkReceiver could return B_INTERRUPTED in that case (it didn't check the return value of port_buffer_size()) which the app_server misinterpreted and quit itself... this fixes the hanging part of bug #1298. * But the input_server still wasn't restarted, because the Registrar had it still listed as being running. Now, the Registrar checks not just periodically for died teams, it will also check for it when a new application registers itself. This fixes the rest of bug #1298. * Removed the old (disabled) R5 style input_server launch mechanism from the app_server. * MessageLooper now prints a bit more information when a port is supposed to have been deleted. * The default implementation of MessageLooper::_GetLooperName() is now returning the name of the semaphore of its BLocker instead of "unnamed looper". git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22115 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
25938e2538
commit
a632458d8e
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2006, Haiku.
|
||||
* Copyright 2001-2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -161,11 +161,14 @@ LinkReceiver::AdjustReplyBuffer(bigtime_t timeout)
|
||||
fRecvBufferSize = kInitialBufferSize;
|
||||
} else {
|
||||
STRACE(("info: LinkReceiver getting port_buffer_size().\n"));
|
||||
|
||||
ssize_t bufferSize;
|
||||
if (timeout == B_INFINITE_TIMEOUT)
|
||||
bufferSize = port_buffer_size(fReceivePort);
|
||||
else
|
||||
bufferSize = port_buffer_size_etc(fReceivePort, B_TIMEOUT, timeout);
|
||||
do {
|
||||
bufferSize = port_buffer_size_etc(fReceivePort,
|
||||
timeout == B_INFINITE_TIMEOUT ? B_RELATIVE_TIMEOUT : 0,
|
||||
timeout);
|
||||
} while (bufferSize == B_INTERRUPTED);
|
||||
|
||||
STRACE(("info: LinkReceiver got port_buffer_size() = %ld.\n", bufferSize));
|
||||
|
||||
if (bufferSize < 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2006, Haiku, Inc.
|
||||
* Copyright (c) 2001-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
@ -113,67 +113,6 @@ AppServer::RunLooper()
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*!
|
||||
\brief Starts Input Server
|
||||
*/
|
||||
void
|
||||
AppServer::_LaunchInputServer()
|
||||
{
|
||||
// We are supposed to start the input_server, but it's a BApplication
|
||||
// that depends on the registrar running, which is started after app_server
|
||||
// so we wait on roster thread to launch the input server
|
||||
|
||||
fISThreadID = B_ERROR;
|
||||
|
||||
while (!BRoster::Private().IsMessengerValid(false) && !fQuitting) {
|
||||
snooze(250000);
|
||||
BRoster::Private::DeleteBeRoster();
|
||||
BRoster::Private::InitBeRoster();
|
||||
}
|
||||
|
||||
if (fQuitting)
|
||||
return;
|
||||
|
||||
// we use an area for cursor data communication with input_server
|
||||
// area id and sem id are sent to the input_server
|
||||
|
||||
if (fCursorArea < B_OK)
|
||||
fCursorArea = create_area("isCursor", (void**) &fCursorAddr, B_ANY_ADDRESS, B_PAGE_SIZE, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (fCursorSem < B_OK)
|
||||
fCursorSem = create_sem(0, "isSem");
|
||||
|
||||
int32 arg_c = 1;
|
||||
char **arg_v = (char **)malloc(sizeof(char *) * (arg_c + 1));
|
||||
#if TEST_MODE
|
||||
arg_v[0] = strdup("/boot/home/svnhaiku/trunk/distro/x86.R1/beos/system/servers/input_server");
|
||||
#else
|
||||
arg_v[0] = strdup("/system/servers/input_server");
|
||||
#endif
|
||||
arg_v[1] = NULL;
|
||||
fISThreadID = load_image(arg_c, (const char**)arg_v, (const char **)environ);
|
||||
free(arg_v[0]);
|
||||
|
||||
int32 tmpbuf[2] = {fCursorSem, fCursorArea};
|
||||
int32 code = 0;
|
||||
send_data(fISThreadID, code, (void *)tmpbuf, sizeof(tmpbuf));
|
||||
|
||||
resume_thread(fISThreadID);
|
||||
setpgid(fISThreadID, 0);
|
||||
|
||||
// we receive
|
||||
|
||||
thread_id sender;
|
||||
code = receive_data(&sender, (void *)tmpbuf, sizeof(tmpbuf));
|
||||
fISASPort = tmpbuf[0];
|
||||
fISPort = tmpbuf[1];
|
||||
|
||||
// if at any time, one of these ports is error prone, it might mean input_server is gone
|
||||
// then relaunch input_server
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief Creates a desktop object for an authorized user
|
||||
*/
|
||||
@ -299,12 +238,6 @@ AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
/*!
|
||||
\brief Entry function to run the entire server
|
||||
\param argc Number of command-line arguments present
|
||||
\param argv String array of the command-line arguments
|
||||
\return -1 if the app_server is already running, 0 if everything's OK.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
|
@ -118,7 +118,12 @@ MessageLooper::_PrepareQuit()
|
||||
void
|
||||
MessageLooper::_GetLooperName(char* name, size_t length)
|
||||
{
|
||||
strcpy(name, "unnamed looper");
|
||||
sem_id semaphore = Sem();
|
||||
sem_info info;
|
||||
if (get_sem_info(semaphore, &info) == B_OK)
|
||||
strlcpy(name, info.name, length);
|
||||
else
|
||||
strlcpy(name, "unnamed looper", length);
|
||||
}
|
||||
|
||||
|
||||
@ -138,7 +143,10 @@ MessageLooper::_MessageLooper()
|
||||
status_t status = receiver.GetNextMessage(code);
|
||||
if (status < B_OK) {
|
||||
// that shouldn't happen, it's our port
|
||||
printf("Someone deleted our message port!\n");
|
||||
char name[256];
|
||||
_GetLooperName(name, 256);
|
||||
printf("MessageLooper \"%s\": Someone deleted our message port %ld, %s!\n",
|
||||
name, receiver.Port(), strerror(status));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,63 +1,46 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2002, OpenBeOS
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// File Name: RosterAppInfo.cpp
|
||||
// Author: Ingo Weinhold (bonefish@users.sf.net)
|
||||
// Description: An extended app_info.
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <string.h>
|
||||
//! An extended app_info.
|
||||
|
||||
#include "RosterAppInfo.h"
|
||||
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
// constructor
|
||||
RosterAppInfo::RosterAppInfo()
|
||||
: app_info(),
|
||||
state(APP_STATE_UNREGISTERED),
|
||||
token(0),
|
||||
registration_time(0)
|
||||
: app_info(),
|
||||
state(APP_STATE_UNREGISTERED),
|
||||
token(0),
|
||||
registration_time(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Init
|
||||
void
|
||||
RosterAppInfo::Init(thread_id thread, team_id team, port_id port, uint32 flags,
|
||||
const entry_ref *ref, const char *signature)
|
||||
const entry_ref *ref, const char *signature)
|
||||
{
|
||||
this->thread = thread;
|
||||
this->team = team;
|
||||
this->port = port;
|
||||
this->flags = flags;
|
||||
this->ref = *ref;
|
||||
if (signature) {
|
||||
strncpy(this->signature, signature, B_MIME_TYPE_LENGTH - 1);
|
||||
this->signature[B_MIME_TYPE_LENGTH - 1] = '\0';
|
||||
} else
|
||||
if (signature)
|
||||
strlcpy(this->signature, signature, B_MIME_TYPE_LENGTH);
|
||||
else
|
||||
this->signature[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
// Clone
|
||||
RosterAppInfo *
|
||||
RosterAppInfo::Clone() const
|
||||
@ -70,3 +53,13 @@ RosterAppInfo::Clone() const
|
||||
clone->registration_time = registration_time;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
// IsRunning
|
||||
bool
|
||||
RosterAppInfo::IsRunning() const
|
||||
{
|
||||
team_info teamInfo;
|
||||
return get_team_info(team, &teamInfo) == B_OK;
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2002, OpenBeOS
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// File Name: RosterAppInfo.h
|
||||
// Author: Ingo Weinhold (bonefish@users.sf.net)
|
||||
// Description: An extended app_info.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ROSTER_APP_INFO_H
|
||||
#define ROSTER_APP_INFO_H
|
||||
|
||||
@ -45,9 +23,10 @@ struct RosterAppInfo : app_info {
|
||||
|
||||
RosterAppInfo();
|
||||
void Init(thread_id thread, team_id team, port_id port, uint32 flags,
|
||||
const entry_ref *ref, const char *signature);
|
||||
const entry_ref *ref, const char *signature);
|
||||
|
||||
RosterAppInfo *Clone() const;
|
||||
bool IsRunning() const;
|
||||
};
|
||||
|
||||
#endif // ROSTER_APP_INFO_H
|
||||
|
@ -179,24 +179,26 @@ PRINT(("full registration: %d\n", fullReg));
|
||||
uint32 token = 0;
|
||||
|
||||
uint32 launchFlags = flags & B_LAUNCH_MASK;
|
||||
BEntry entry(&ref);
|
||||
if (!entry.Exists())
|
||||
SET_ERROR(error, B_ENTRY_NOT_FOUND);
|
||||
|
||||
if (error == B_OK)
|
||||
_ValidateRunning(ref, signature);
|
||||
|
||||
// entry_ref
|
||||
if (error == B_OK) {
|
||||
// the entry_ref must be valid
|
||||
if (BEntry(&ref).Exists()) {
|
||||
PRINT(("flags: %lx\n", flags));
|
||||
PRINT(("ref: %ld, %lld, %s\n", ref.device, ref.directory, ref.name));
|
||||
// check single/exclusive launchers
|
||||
RosterAppInfo *info = NULL;
|
||||
if ((launchFlags == B_SINGLE_LAUNCH
|
||||
|| launchFlags == B_EXCLUSIVE_LAUNCH)
|
||||
&& (((info = fRegisteredApps.InfoFor(&ref)))
|
||||
|| ((info = fEarlyPreRegisteredApps.InfoFor(&ref))))) {
|
||||
SET_ERROR(error, B_ALREADY_RUNNING);
|
||||
otherTeam = info->team;
|
||||
}
|
||||
} else
|
||||
SET_ERROR(error, B_ENTRY_NOT_FOUND);
|
||||
// check single/exclusive launchers
|
||||
RosterAppInfo *info = NULL;
|
||||
if ((launchFlags == B_SINGLE_LAUNCH
|
||||
|| launchFlags == B_EXCLUSIVE_LAUNCH)
|
||||
&& ((info = info = fRegisteredApps.InfoFor(&ref)) != NULL
|
||||
|| (info = fEarlyPreRegisteredApps.InfoFor(&ref)) != NULL)) {
|
||||
SET_ERROR(error, B_ALREADY_RUNNING);
|
||||
otherTeam = info->team;
|
||||
}
|
||||
}
|
||||
|
||||
// signature
|
||||
@ -1274,8 +1276,7 @@ TRoster::CheckSanity()
|
||||
// not early (pre-)registered applications
|
||||
AppInfoList obsoleteApps;
|
||||
for (AppInfoList::Iterator it = fRegisteredApps.It(); it.IsValid(); ++it) {
|
||||
team_info teamInfo;
|
||||
if (get_team_info((*it)->team, &teamInfo) != B_OK)
|
||||
if (!(*it)->IsRunning())
|
||||
obsoleteApps.AddInfo(*it);
|
||||
}
|
||||
// remove the apps
|
||||
@ -1750,7 +1751,30 @@ TRoster::_HandleGetRecentEntries(BMessage *request)
|
||||
FUNCTION_END();
|
||||
}
|
||||
|
||||
// _IsSystemApp
|
||||
|
||||
/*!
|
||||
\brief Checks all registered apps for \a ref and \a signature if
|
||||
they are still alive, and removes those that aren't.
|
||||
*/
|
||||
void
|
||||
TRoster::_ValidateRunning(const entry_ref& ref, const char* signature)
|
||||
{
|
||||
while (true) {
|
||||
// get info via ref or signature
|
||||
RosterAppInfo* info = fRegisteredApps.InfoFor(&ref);
|
||||
if (info == NULL && signature != NULL)
|
||||
info = fRegisteredApps.InfoFor(signature);
|
||||
|
||||
// if app is alive or does not exist, we can exit
|
||||
if (info == NULL || info->IsRunning())
|
||||
return;
|
||||
|
||||
RemoveApp(info);
|
||||
delete info;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TRoster::_IsSystemApp(RosterAppInfo *info) const
|
||||
{
|
||||
|
@ -84,20 +84,20 @@ private:
|
||||
void _AppDeactivated(RosterAppInfo *info);
|
||||
|
||||
// helper functions
|
||||
static status_t _AddMessageAppInfo(BMessage *message,
|
||||
const app_info *info);
|
||||
static status_t _AddMessageWatchingInfo(BMessage *message,
|
||||
const app_info *info);
|
||||
static status_t _AddMessageAppInfo(BMessage* message, const app_info* info);
|
||||
static status_t _AddMessageWatchingInfo(BMessage* message,
|
||||
const app_info* info);
|
||||
uint32 _NextToken();
|
||||
|
||||
void _AddIARRequest(IARRequestMap& map, int32 key, BMessage* request);
|
||||
void _ReplyToIARRequests(BMessageQueue *requests,
|
||||
const RosterAppInfo *info);
|
||||
void _ReplyToIARRequest(BMessage *request, const RosterAppInfo *info);
|
||||
void _ReplyToIARRequests(BMessageQueue* requests,
|
||||
const RosterAppInfo* info);
|
||||
void _ReplyToIARRequest(BMessage* request, const RosterAppInfo* info);
|
||||
|
||||
void _HandleGetRecentEntries(BMessage *request);
|
||||
void _HandleGetRecentEntries(BMessage* request);
|
||||
|
||||
bool _IsSystemApp(RosterAppInfo *info) const;
|
||||
void _ValidateRunning(const entry_ref& ref, const char* signature);
|
||||
bool _IsSystemApp(RosterAppInfo* info) const;
|
||||
|
||||
status_t _LoadRosterSettings(const char *path = NULL);
|
||||
status_t _SaveRosterSettings(const char *path = NULL);
|
||||
@ -109,7 +109,7 @@ private:
|
||||
AppInfoList fEarlyPreRegisteredApps;
|
||||
IARRequestMap fIARRequestsByID;
|
||||
IARRequestMap fIARRequestsByToken;
|
||||
RosterAppInfo *fActiveApp;
|
||||
RosterAppInfo* fActiveApp;
|
||||
WatchingService fWatchingService;
|
||||
RecentApps fRecentApps;
|
||||
RecentEntries fRecentDocuments;
|
||||
|
Loading…
Reference in New Issue
Block a user