haiku/docs/develop/servers/app_server/ServerApp.htm

331 lines
15 KiB
HTML
Raw Normal View History

<HTML>
<HEAD>
<TITLE>ServerApp.htm</TITLE>
<style type="text/css">
<!--
.Default {background-color: rgb(255,255,255); color: rgb(0,0,0); font-family: 'Dutch801 Rm BT'; font-size: 12pt}
.OBOS-Function-Def {background-color: rgb(255,255,255); color: rgb(0,0,0); font-family: 'Dutch801 Rm BT'; font-size: 16pt}
.OBOS-Title {background-color: rgb(255,255,255); color: rgb(0,128,0); font-family: 'Dutch801 Rm BT'; font-size: 24pt}
.Text-Background {background-color: rgb(255,255,255)}
.GR-Default {}
.Body {margin: 0px}
.Footer {margin: 0px}
.Header {margin: 0px}
.WP-Default {text-align: left; text-indent: 0px; margin-left: 0px; margin-right: 0px}
-->
</style>
</HEAD>
<BODY BGCOLOR="#ffffff">
<DIV class="sheet" id="Sheet 1">
<P class="Body" style="margin: 0px"><span class="OBOS-Title">ServerApp class</span><span style="color: rgb(0,0,0); font-size: 24pt"></span></P>
<P class="Body" style="margin: 0px"><BR>
</P>
<P class="Body" style="margin: 0px">ServerApps are the server-side counterpart to BApplications. They monitor for messages for the BApplication, create BWindows and BBitmaps, and provide a channel for the app_server to send messages to a user application without having a window.</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<HR>
</P>
<P class="Body" style="margin: 0px">Member Functions</P>
<P class="Body" style="margin: 0px"><BR>
</P>
<TABLE WIDTH=681 HEIGHT=156 BORDER=1 CELLPADDING=1 CELLSPACING=2>
<TR>
<TD WIDTH=251 HEIGHT=32>
<P class="Body" style="margin: 0px">ServerApp(port_id sendport, port_id rcvport, const char *signature, thread_id thread_bapp)</P>
</TD>
<TD WIDTH=260 HEIGHT=32>
<P class="Body" style="margin: 0px">~ServerApp(void)</P>
</TD>
</TR>
<TR>
<TD WIDTH=251 HEIGHT=17>
<P class="Body" style="margin: 0px">bool Run(void)</P>
</TD>
<TD WIDTH=260 HEIGHT=17>
<P class="Body" style="margin: 0px">static int32 MonitorApp(void *data)</P>
</TD>
</TR>
<TR>
<TD WIDTH=251 HEIGHT=17>
<P class="Body" style="margin: 0px">void Lock(void)</P>
</TD>
<TD WIDTH=260 HEIGHT=17>
<P class="Body" style="margin: 0px">void Unlock(void)</P>
</TD>
</TR>
<TR>
<TD WIDTH=251 HEIGHT=17>
<P class="Body" style="margin: 0px">bool IsLocked(void)</P>
</TD>
<TD WIDTH=260 HEIGHT=17>
<P class="Body" style="margin: 0px">void WindowBroadcast(int32 code)</P>
</TD>
</TR>
<TR>
<TD WIDTH=251 HEIGHT=17>
<P class="Body" style="margin: 0px">bool IsActive(void)</P>
</TD>
<TD WIDTH=260 HEIGHT=17>
<P class="Body" style="margin: 0px">bool PingTarget(void)</P>
</TD>
</TR>
<TR>
<TD WIDTH=251 HEIGHT=17>
<P class="Body" style="margin: 0px">void DispatchMessage(int32 code, int8 *buffer)</P>
</TD>
<TD WIDTH=260 HEIGHT=17>
&nbsp;
</TD>
</TR>
</TABLE>
<P class="Body" style="margin: 0px"><BR>
<BR>
Global Functions</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<HR>
</P>
<P class="Body" style="margin: 0px"><span class="OBOS-Function-Def">ServerApp(port_id sendport, port_id rcvport, const char *sig, thread_id thread_bapp)</span></P>
<P class="Body" style="margin: 0px"><BR>
1) Create the window list as empty</P>
<P class="Body" style="margin: 0px">2) Save sendport, rcvport, sig, and thread_bapp to the respective ServerApp members</P>
<P class="Body" style="margin: 0px">3) Set quit_app flag to false</P>
<P class="Body" style="margin: 0px">4) Create the window list lock</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<span class="OBOS-Function-Def">~ServerApp(void)</span><span style="font-size: 16pt"></span></P>
<P class="Body" style="margin: 0px"><BR>
1) Empty and delete window list and accompanying windows</P>
<P class="Body" style="margin: 0px">2) Wait for the monitoring thread to exit</P>
<P class="Body" style="margin: 0px">3) Call CursorManager::RemoveAppCursors(this)</P>
<P class="Body" style="margin: 0px">4) Delete the window list lock</P>
<P class="Body" style="margin: 0px">5) If monitoring thread still active, kill it (in case app is deleted without a quit message)</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<span class="OBOS-Function-Def">bool Run(void)</span></P>
<P class="Body" style="margin: 0px"><BR>
Run() simply makes a ServerApp start monitoring for messages from its BApplication, telling it to quit if there is a problem.</P>
<P class="Body" style="margin: 0px"><BR>
1) Spawn the monitoring thread (which utilizes MonitorApp())
2) If any error, tell the BApplication to quit, spit an error to stderr, and return false</P>
<P class="Body" style="margin: 0px">3) Resume the monitoring thread</P>
<P class="Body" style="margin: 0px">4) Return true</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<span class="OBOS-Function-Def">static int32 MonitorApp(void *data)</span></P>
<P class="Body" style="margin: 0px"><BR>
Thread function for monitoring for messages from the ServerApp's BApplication.</P>
<P class="Body" style="margin: 0px"><BR>
1) Call port_buffer_size - which will block if the port is empty</P>
<P class="Body" style="margin: 0px">2) Allocate a buffer on the heap if the port buffer size is greater than 0</P>
<P class="Body" style="margin: 0px">3) Read the port</P>
<P class="Body" style="margin: 0px">4) Pass specified messages to DispatchMessage() for processing, spitting out an error message to stderr if the message's code is unrecognized</P>
<P class="Body" style="margin: 0px">5) Return from DispatchMessage() and free the message buffer if one was allocated</P>
<P class="Body" style="margin: 0px">6) If the message code matches the B_QUIT_REQUESTED definition and the quit_app flag is true, fall out of the infinite message-monitoring loop. Otherwise continue to next iteration</P>
<P class="Body" style="text-align: left; margin: 0px">7) Send a DELETE_APP message to the server's main message to force deleting of the ServerApp instance and exit</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<BR>
<span class="OBOS-Function-Def">bool IsActive(void)</span></P>
<P class="Body" style="margin: 0px"><BR>
Used for determining whether the application is the active one. Simply returns the isactive flag.</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<span class="OBOS-Function-Def">void PingTarget(void)</span></P>
<P class="Body" style="margin: 0px"><BR>
PingTarget() is called only from the Picasso thread of the app_server in order to determine whether its respective BApplication still exists. BApplications have been known to crash from time to time without the common courtesy of notifying the server of its intentions. ;D</P>
<P class="Body" style="margin: 0px"><BR>
1) Call get_thread_info() with the app's thread_id</P>
<P class="Body" style="margin: 0px">2) if it returns anything but B_OK, return false. Otherwise, return true.</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
<span class="OBOS-Function-Def">void DispatchMessage(int32 code, int8 *buffer)</span></P>
<P class="Body" style="margin: 0px"><BR>
DispatchMessage implements all the code necessary to respond to a given message sent to the ServerApp on its receiving message port. This allows for clearer and more manageable code.</P>
<P class="Body" style="margin: 0px"><BR>
CREATE_WINDOW:</P>
<P class="Body" style="margin: 0px"><BR>
Sent by a new BWindow object via synchronous PortLink messaging. Set up the corresponding ServerWindow and reply to the BWindow with the new port to which it will send future communications with the App Server.</P>
<P class="Body" style="margin: 0px"><BR>
Attached Data:</P>
<P class="Body" style="margin: 0px"><BR>
</P>
<P class="Body" style="text-align: center; margin: 0px"></P>
<TABLE WIDTH=573 HEIGHT=156 BORDER=1 CELLPADDING=1 CELLSPACING=2>
<TR>
<TD WIDTH=112 HEIGHT=32>
<P class="Body" style="margin: 0px">port_id reply_port</P>
</TD>
<TD WIDTH=318 HEIGHT=32>
<P class="Body" style="margin: 0px">port to which the server is to reply in response to the current message</P>
</TD>
</TR>
<TR>
<TD WIDTH=112 HEIGHT=17>
<P class="Body" style="margin: 0px">BRect wframe</P>
</TD>
<TD WIDTH=318 HEIGHT=17>
<P class="Body" style="margin: 0px">frame of the requesting BWindow</P>
</TD>
</TR>
<TR>
<TD WIDTH=112 HEIGHT=17>
<P class="Body" style="margin: 0px">uint32 wflags</P>
</TD>
<TD WIDTH=318 HEIGHT=17>
<P class="Body" style="margin: 0px">flag data of the requesting BWindow</P>
</TD>
</TR>
<TR>
<TD WIDTH=112 HEIGHT=17>
<P class="Body" style="margin: 0px">port_id win_port</P>
</TD>
<TD WIDTH=318 HEIGHT=17>
<P class="Body" style="margin: 0px">receiver port of the requesting BWindow</P>
</TD>
</TR>
<TR>
<TD WIDTH=112 HEIGHT=17>
<P class="Body" style="margin: 0px">uint32 workspaces</P>
</TD>
<TD WIDTH=318 HEIGHT=17>
<P class="Body" style="margin: 0px">workspaces on which the BWindow is to appear</P>
</TD>
</TR>
<TR>
<TD WIDTH=112 HEIGHT=17>
<P class="Body" style="margin: 0px">const char *title</P>
</TD>
<TD WIDTH=318 HEIGHT=17>
<P class="Body" style="margin: 0px">title of the requesting BWindow</P>
</TD>
</TR>
</TABLE>
<P class="Body" style="text-align: center; margin: 0px"><BR>
</P>
<P class="Body" style="margin: 0px"><BR>
1) Get all attached data</P>
<P class="Body" style="margin: 0px">2) Acquire the window list lock</P>
<P class="Body" style="margin: 0px">3) Allocate a ServerWindow object and add it to the list</P>
<P class="Body" style="margin: 0px">4) Release window list lock</P>
<P class="Body" style="margin: 0px">5) Send the message SET_SERVER_PORT (with the ServerWindow's receiver port attached to the reply port</P>
<P class="Body" style="margin: 0px"><BR>
<BR>
DELETE_APP:</P>
<P class="Body" style="margin: 0px"><BR>
Sent by a ServerWindow when told to quit. It is identified by the unique ID assigned to its thread.</P>
<P class="Body" style="margin: 0px"><BR>
Attached Data:</P>
<P class="Body" style="margin: 0px"><BR>
</P>
<P class="Body" style="text-align: center; margin: 0px"></P>
<TABLE WIDTH=568 HEIGHT=22 BORDER=1 CELLPADDING=1 CELLSPACING=2>
<TR>
<TD WIDTH=132 HEIGHT=17>
<P class="Body" style="margin: 0px">thread_id win_thread</P>
</TD>
<TD WIDTH=294 HEIGHT=17>
<P class="Body" style="margin: 0px">Thread id of the ServerWindow sending this message</P>
</TD>
</TR>
</TABLE>
<P class="Body" style="text-align: center; margin: 0px"><BR>
</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
1) Get window's thread_id</P>
<P class="Body" style="text-align: left; margin: 0px">2) Acquire window list lock</P>
<P class="Body" style="text-align: left; margin: 0px">3) Iterate through the window list, searching for the ServerWindow object with the sent thread_id</P>
<P class="Body" style="text-align: left; margin: 0px">4) Remove the object from the list and delete it</P>
<P class="Body" style="text-align: left; margin: 0px">5) Release window list lock</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
<BR>
SET_CURSOR_DATA:</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
Received from the ServerApp's BApplication when SetCursor(const void *) is called. </P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
</P>
<P class="Body" style="margin: 0px">Attached Data:</P>
<P class="Body" style="margin: 0px"><BR>
</P>
<P class="Body" style="text-align: center; margin: 0px"></P>
<TABLE WIDTH=573 HEIGHT=22 BORDER=1 CELLPADDING=1 CELLSPACING=2>
<TR>
<TD WIDTH=112 HEIGHT=17>
<P class="Body" style="margin: 0px">int8 cursor[68]</P>
</TD>
<TD WIDTH=318 HEIGHT=17>
<P class="Body" style="margin: 0px">Cursor data in the format as defined in the BeBook</P>
</TD>
</TR>
</TABLE>
<P class="Body" style="text-align: center; margin: 0px"><BR>
</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
1) Create a ServerCursor from the attached cursor data</P>
<P class="Body" style="text-align: left; margin: 0px">2) Add the new ServerCursor to the CursorManager and then call CursorManager::SetCursor</P>
<P class="Body" style="text-align: left; margin: 0px">
</P>
<P class="Body" style="text-align: left; margin: 0px">SET_CURSOR_BCURSOR:</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
Received from the ServerApp's BApplication when SetCursor(BCursor *, bool) is called. </P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
</P>
<P class="Body" style="margin: 0px">Attached Data:</P>
<P class="Body" style="margin: 0px"><BR>
</P>
<P class="Body" style="text-align: center; margin: 0px"></P>
<TABLE WIDTH=573 HEIGHT=22 BORDER=1 CELLPADDING=1 CELLSPACING=2>
<TR>
<TD WIDTH=112 HEIGHT=17>
<P class="Body" style="margin: 0px">int32 token</P>
</TD>
<TD WIDTH=318 HEIGHT=17>
<P class="Body" style="margin: 0px">Token identifier of cursor in the BCursor class</P>
</TD>
</TR>
</TABLE>
<P class="Body" style="text-align: center; margin: 0px"><BR>
</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
1) Get the attached token and call CursorManager::SetCursor(token)</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
<BR>
B_QUIT_REQUESTED:</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
Received from the BApplication when quits, so set the quit flag and ask the server to delete the object</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
Attached Data: None</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
1) Set quit_app flag to true</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
<BR>
UPDATE_DECORATOR:</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
Received from the poller thread when the window decorator for the system has changed. </P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
Attached Data: None</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
1) Call WindowBroadcast(UPDATE_DECORATOR)</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
<BR>
<span class="OBOS-Function-Def">void WindowBroadcast(int32 code)</span></P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
Similar to AppServer::Broadcast(), this sends a message to all ServerWindows which belong to the ServerApp.</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
1) Acquire window list lock</P>
<P class="Body" style="text-align: left; margin: 0px">2) Create a PortLink instance and set its message code to the passed parameter.</P>
<P class="Body" style="text-align: left; margin: 0px">3) Iterate through the window list, targeting the PortLink instance to each ServerWindow's message port and calling Flush().</P>
<P class="Body" style="text-align: left; margin: 0px">4) Release window list lock</P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
<BR>
<span class="OBOS-Function-Def">void Lock(void)</span></P>
<P class="Body" style="text-align: left; margin: 0px"><span class="OBOS-Function-Def">void Unlock(void)</span></P>
<P class="Body" style="text-align: left; margin: 0px"><span class="OBOS-Function-Def">bool IsLocked(void)</span></P>
<P class="Body" style="text-align: left; margin: 0px"><BR>
These functions are used to regulate access to the ServerApp's data members. Lock() acquires the internal semaphore, Unlock() releases it, and IsLocked returns true only if the semaphore's value is positive.</P>
<DIV class="layer" id="Layer 1">
</DIV>
</DIV>
</BODY>
</HTML>