* delete_owned_ports() no longer scans the whole port array for ports belonging
to the owning team. * Instead, the team now maintains a list containing the ports it owns. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33771 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -32,7 +32,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
status_t port_init(struct kernel_args *args);
|
status_t port_init(struct kernel_args *args);
|
||||||
int delete_owned_ports(team_id owner);
|
void delete_owned_ports(struct team* team);
|
||||||
int32 port_max_ports(void);
|
int32 port_max_ports(void);
|
||||||
int32 port_used_ports(void);
|
int32 port_used_ports(void);
|
||||||
|
|
||||||
@@ -41,11 +41,8 @@ status_t deselect_port(int32 object, struct select_info *info, bool kernel);
|
|||||||
|
|
||||||
// currently private API
|
// currently private API
|
||||||
status_t writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
status_t writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
||||||
size_t vecCount, size_t bufferSize, uint32 flags,
|
size_t vecCount, size_t bufferSize, uint32 flags,
|
||||||
bigtime_t timeout);
|
bigtime_t timeout);
|
||||||
|
|
||||||
// temp: test
|
|
||||||
void port_test(void);
|
|
||||||
|
|
||||||
// user syscalls
|
// user syscalls
|
||||||
port_id _user_create_port(int32 queueLength, const char *name);
|
port_id _user_create_port(int32 queueLength, const char *name);
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ struct team {
|
|||||||
struct list image_list;
|
struct list image_list;
|
||||||
struct list watcher_list;
|
struct list watcher_list;
|
||||||
struct list sem_list;
|
struct list sem_list;
|
||||||
|
struct list port_list;
|
||||||
struct arch_team arch_info;
|
struct arch_team arch_info;
|
||||||
|
|
||||||
addr_t user_data;
|
addr_t user_data;
|
||||||
|
|||||||
+51
-38
@@ -52,6 +52,7 @@ struct port_message : DoublyLinkedListLinkImpl<port_message> {
|
|||||||
typedef DoublyLinkedList<port_message> MessageList;
|
typedef DoublyLinkedList<port_message> MessageList;
|
||||||
|
|
||||||
struct port_entry {
|
struct port_entry {
|
||||||
|
struct list_link team_link;
|
||||||
port_id id;
|
port_id id;
|
||||||
team_id owner;
|
team_id owner;
|
||||||
int32 capacity;
|
int32 capacity;
|
||||||
@@ -563,38 +564,52 @@ copy_port_message(port_message* message, int32* _code, void* buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
uninit_port_locked(struct port_entry& port)
|
||||||
|
{
|
||||||
|
int32 id = port.id;
|
||||||
|
|
||||||
|
// mark port as invalid
|
||||||
|
port.id = -1;
|
||||||
|
free((char*)port.lock.name);
|
||||||
|
port.lock.name = NULL;
|
||||||
|
|
||||||
|
while (port_message* message = port.messages.RemoveHead()) {
|
||||||
|
put_port_message(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
notify_port_select_events(id % sMaxPorts, B_EVENT_INVALID);
|
||||||
|
port.select_infos = NULL;
|
||||||
|
|
||||||
|
// Release the threads that were blocking on this port.
|
||||||
|
// read_port() will see the B_BAD_PORT_ID return value, and act accordingly
|
||||||
|
port.read_condition.NotifyAll(B_BAD_PORT_ID);
|
||||||
|
port.write_condition.NotifyAll(B_BAD_PORT_ID);
|
||||||
|
sNotificationService.Notify(PORT_REMOVED, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - private kernel API
|
// #pragma mark - private kernel API
|
||||||
|
|
||||||
|
|
||||||
/*! This function cycles through the ports table, deleting all
|
/*! This function delets all the ports that are owned by the passed team.
|
||||||
the ports that are owned by the passed team_id
|
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
delete_owned_ports(team_id owner)
|
delete_owned_ports(struct team* team)
|
||||||
{
|
{
|
||||||
// TODO: investigate maintaining a list of ports in the team
|
TRACE(("delete_owned_ports(owner = %ld)\n", team->id));
|
||||||
// to make this simpler and more efficient.
|
|
||||||
|
|
||||||
TRACE(("delete_owned_ports(owner = %ld)\n", owner));
|
struct list queue;
|
||||||
|
|
||||||
MutexLocker locker(sPortsLock);
|
{
|
||||||
|
InterruptsSpinLocker locker(gTeamSpinlock);
|
||||||
int32 count = 0;
|
list_move_to_list(&team->port_list, &queue);
|
||||||
|
|
||||||
for (int32 i = 0; i < sMaxPorts; i++) {
|
|
||||||
if (sPorts[i].id != -1 && sPorts[i].owner == owner) {
|
|
||||||
port_id id = sPorts[i].id;
|
|
||||||
|
|
||||||
locker.Unlock();
|
|
||||||
|
|
||||||
delete_port(id);
|
|
||||||
count++;
|
|
||||||
|
|
||||||
locker.Lock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
while (port_entry* port = (port_entry*)list_remove_head_item(&queue)) {
|
||||||
|
MutexLocker locker(port->lock);
|
||||||
|
uninit_port_locked(*port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -693,6 +708,10 @@ create_port(int32 queueLength, const char* name)
|
|||||||
if (queueLength < 1 || queueLength > MAX_QUEUE_LENGTH)
|
if (queueLength < 1 || queueLength > MAX_QUEUE_LENGTH)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
struct team* team = thread_get_current_thread()->team;
|
||||||
|
if (team == NULL)
|
||||||
|
return B_BAD_TEAM_ID;
|
||||||
|
|
||||||
MutexLocker locker(sPortsLock);
|
MutexLocker locker(sPortsLock);
|
||||||
|
|
||||||
// check early on if there are any free port slots to use
|
// check early on if there are any free port slots to use
|
||||||
@@ -730,6 +749,11 @@ create_port(int32 queueLength, const char* name)
|
|||||||
sPorts[i].total_count = 0;
|
sPorts[i].total_count = 0;
|
||||||
sPorts[i].select_infos = NULL;
|
sPorts[i].select_infos = NULL;
|
||||||
|
|
||||||
|
{
|
||||||
|
InterruptsSpinLocker teamLocker(gTeamSpinlock);
|
||||||
|
list_add_item(&team->port_list, &sPorts[i].team_link);
|
||||||
|
}
|
||||||
|
|
||||||
port_id id = sPorts[i].id;
|
port_id id = sPorts[i].id;
|
||||||
|
|
||||||
T(Create(sPorts[i]));
|
T(Create(sPorts[i]));
|
||||||
@@ -800,23 +824,12 @@ delete_port(port_id id)
|
|||||||
|
|
||||||
T(Delete(sPorts[slot]));
|
T(Delete(sPorts[slot]));
|
||||||
|
|
||||||
// mark port as invalid
|
{
|
||||||
sPorts[slot].id = -1;
|
InterruptsSpinLocker teamLocker(gTeamSpinlock);
|
||||||
free((char*)sPorts[slot].lock.name);
|
list_remove_link(&sPorts[slot].team_link);
|
||||||
sPorts[slot].lock.name = NULL;
|
|
||||||
|
|
||||||
while (port_message* message = sPorts[slot].messages.RemoveHead()) {
|
|
||||||
put_port_message(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_port_select_events(slot, B_EVENT_INVALID);
|
uninit_port_locked(sPorts[slot]);
|
||||||
sPorts[slot].select_infos = NULL;
|
|
||||||
|
|
||||||
// Release the threads that were blocking on this port.
|
|
||||||
// read_port() will see the B_BAD_PORT_ID return value, and act accordingly
|
|
||||||
sPorts[slot].read_condition.NotifyAll(B_BAD_PORT_ID);
|
|
||||||
sPorts[slot].write_condition.NotifyAll(B_BAD_PORT_ID);
|
|
||||||
sNotificationService.Notify(PORT_REMOVED, id);
|
|
||||||
|
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,10 @@
|
|||||||
* Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*! Team functions */
|
/*! Team functions */
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -798,6 +800,7 @@ create_team_struct(const char *name, bool kernel)
|
|||||||
team->job_control_entry->team = team;
|
team->job_control_entry->team = team;
|
||||||
|
|
||||||
list_init(&team->sem_list);
|
list_init(&team->sem_list);
|
||||||
|
list_init(&team->port_list);
|
||||||
list_init(&team->image_list);
|
list_init(&team->image_list);
|
||||||
list_init(&team->watcher_list);
|
list_init(&team->watcher_list);
|
||||||
|
|
||||||
@@ -1392,7 +1395,7 @@ exec_team(const char *path, char**& _flatArgs, size_t flatArgsSize,
|
|||||||
delete_team_user_data(team);
|
delete_team_user_data(team);
|
||||||
vm_delete_areas(team->address_space);
|
vm_delete_areas(team->address_space);
|
||||||
xsi_sem_undo(team);
|
xsi_sem_undo(team);
|
||||||
delete_owned_ports(team->id);
|
delete_owned_ports(team);
|
||||||
sem_delete_owned_sems(team);
|
sem_delete_owned_sems(team);
|
||||||
remove_images(team);
|
remove_images(team);
|
||||||
vfs_exec_io_context(team->io_context);
|
vfs_exec_io_context(team->io_context);
|
||||||
@@ -2463,7 +2466,7 @@ team_delete_team(struct team *team)
|
|||||||
vfs_put_io_context(team->io_context);
|
vfs_put_io_context(team->io_context);
|
||||||
delete_realtime_sem_context(team->realtime_sem_context);
|
delete_realtime_sem_context(team->realtime_sem_context);
|
||||||
xsi_sem_undo(team);
|
xsi_sem_undo(team);
|
||||||
delete_owned_ports(teamID);
|
delete_owned_ports(team);
|
||||||
sem_delete_owned_sems(team);
|
sem_delete_owned_sems(team);
|
||||||
remove_images(team);
|
remove_images(team);
|
||||||
vm_delete_address_space(team->address_space);
|
vm_delete_address_space(team->address_space);
|
||||||
|
|||||||
Reference in New Issue
Block a user