Ticket #12319: class_NetworktimeprefletAsAddon.cpp

File class_NetworktimeprefletAsAddon.cpp, 3.9 KB (added by ttcoder, 9 years ago)

One way to invoke Time as described

Line 
1
2
3//#pragma mark - class NetworktimeprefletAsAddon -
4
5
6class NetworktimeprefletAsAddon
7{
8 /*
9 This allows to invoke the /system/preferences/Time preflet.. Not with load_image()
10 but outright with load_add_on() so that we can call its ntp_update_time() function directly.
11 The source for that particular function is here:
12 http://cgit.haiku-os.org/haiku/tree/src/preferences/time/ntp.cpp
13 which is (in the original Time preflet) called from
14 http://cgit.haiku-os.org/haiku/tree/src/preferences/time/NetworkTimeView.cpp
15 */
16
17public:
18
19 NetworktimeprefletAsAddon();
20 ~NetworktimeprefletAsAddon();
21
22 void UpdateSystemTime();
23
24private: // CODE
25
26 static status_t thread_func( void * );
27
28
29private: // DATA
30
31 image_id addonId;
32 thread_id updaterThread;
33};
34
35
36NetworktimeprefletAsAddon::NetworktimeprefletAsAddon()
37: addonId( -1 ),
38 updaterThread( -1 )
39{
40 addonId = load_add_on( "/system/preferences/Time" );
41 if( addonId < B_OK )
42 {
43 printf( "** NetworktimeprefletAsAddon failure: can't load Time preflet: " );
44 perror( strerror(addonId) );
45 }
46 //printf("addonId %ld\n", addonId);
47}
48
49NetworktimeprefletAsAddon::~NetworktimeprefletAsAddon()
50{
51 // make sure to kill the thread dead before we unload_add_on() the add-on
52 // and its TEXT segment which the thread is running, or that will crash good! :
53
54 if( updaterThread > 0 )
55 kill_thread( updaterThread );
56
57 if( addonId > 0 )
58 unload_add_on( addonId );
59}
60
61
62void NetworktimeprefletAsAddon::UpdateSystemTime()
63{
64 status_t (*ntp_update_time)( const char *host, const char** errorString, int32* errorCode )
65 = NULL
66 ;
67 status_t sta = get_image_symbol(
68 addonId,
69 "ntp_update_time__FPCcPPCcPl", // "ntp_update_time" with some gcc2 name-mangling :-/
70 B_SYMBOL_TYPE_TEXT,
71 reinterpret_cast<void**>( &ntp_update_time )
72 );
73 //printf("func %p\n", ntp_update_time);
74
75 if( sta != B_OK || NULL == ntp_update_time )
76 {
77 printf( "** NetworktimeprefletAsAddon: get_image_symbol failure: " );
78 perror( strerror(sta) );
79
80 //
81 return;
82 //
83 }
84
85 updaterThread = spawn_thread(
86 thread_func, "(add-on)ntp_update_time",
87 B_NORMAL_PRIORITY,
88 ntp_update_time
89 );
90 resume_thread( updaterThread );
91
92 // wait for (at most) 2 seconds:
93 for( int i = 0; i < 20; i++ )
94 {
95 snooze( 100000 );
96
97 // "resume_thread" is a good way to test if a thread is still running or not:
98 status_t test = resume_thread( updaterThread );
99 //printf( "0x%lx for updaterThread\n", test );
100 if( B_BAD_THREAD_ID == test )
101 // the thread has exited, no need to wait any longer
102 return;
103 //
104 }
105
106 // if we're here, we've waited for 2 seconds and the thread is STILL running...
107 printf( "* NetworktimeprefletAsAddon: network thread stuck for too long, aborting (will try again later)\n" );
108}
109
110status_t NetworktimeprefletAsAddon::thread_func( void * func_inside_addon )
111{
112 // SUMMARY
113 // - load settings BMessage
114 // - call function
115
116 status_t (*ntp_update_time)( const char *host, const char** errorString, int32* errorCode )
117 = NULL
118 ;
119 (void*)ntp_update_time = func_inside_addon;
120
121 const char * error_string = NULL;
122 int32 error_code = 0;
123 BString server;
124 {
125 // load "~/config/settings/networktime settings":
126 EasyMessage system_settings;
127 {
128 BPath path;
129 find_directory( B_USER_SETTINGS_DIRECTORY, &path );
130 path.Append( "networktime settings" );
131
132 system_settings.LoadFrom( path.Path() );
133 }
134 server = system_settings.String( "server" ); // server[0] contains e.g. "pool.ntp.org"
135
136 // notes:
137 // - passing "invalid.blah" results in message << NTP STATUS = 0x80006003 error_string=<Could not contact server> error_code=0x0 >>
138 // - passing "invalid.com" stays stuck for many seconds (the invalid.com server probably fails to respond to our port probing..)
139 }
140 ;
141 status_t status = ntp_update_time(
142 server,
143 &error_string,
144 &error_code
145 );
146
147 if( B_OK != status )
148 printf( "** NetworktimeprefletAsAddon status = 0x%lx error_string=<%s> error_code=0x%lx\n", status, error_string, error_code );
149
150 return 0;
151}
152