jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

445 lines
15KB

  1. /*
  2. Copyright (C) 2004-2008 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "JackSocketServerChannel.h"
  16. #include "JackRequest.h"
  17. #include "JackServer.h"
  18. #include "JackEngine.h"
  19. #include "JackGlobals.h"
  20. #include "JackClient.h"
  21. #include "JackNotification.h"
  22. #include <assert.h>
  23. using namespace std;
  24. namespace Jack
  25. {
  26. JackSocketServerChannel::JackSocketServerChannel()
  27. {
  28. fThread = JackGlobals::MakeThread(this);
  29. fPollTable = NULL;
  30. fRebuild = true;
  31. }
  32. JackSocketServerChannel::~JackSocketServerChannel()
  33. {
  34. delete fThread;
  35. delete[] fPollTable;
  36. }
  37. int JackSocketServerChannel::Open(const char* server_name, JackServer* server)
  38. {
  39. JackLog("JackSocketServerChannel::Open \n");
  40. fServer = server;
  41. // Prepare request socket
  42. if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) {
  43. JackLog("JackSocketServerChannel::Open : cannot create result listen socket\n");
  44. return -1;
  45. }
  46. // Prepare for poll
  47. BuildPoolTable();
  48. // Start listening
  49. if (fThread->Start() != 0) {
  50. jack_error("Cannot start Jack server listener");
  51. goto error;
  52. }
  53. return 0;
  54. error:
  55. fRequestListenSocket.Close();
  56. return -1;
  57. }
  58. void JackSocketServerChannel::Close()
  59. {
  60. fThread->Kill();
  61. fRequestListenSocket.Close();
  62. }
  63. void JackSocketServerChannel::ClientCreate()
  64. {
  65. JackLog("JackSocketServerChannel::ClientCreate socket\n");
  66. JackClientSocket* socket = fRequestListenSocket.Accept();
  67. if (socket) {
  68. fSocketTable[socket->GetFd()] = make_pair( -1, socket);
  69. fRebuild = true;
  70. } else {
  71. jack_error("Client socket cannot be created");
  72. }
  73. }
  74. void JackSocketServerChannel::ClientAdd(int fd, char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result)
  75. {
  76. JackLog("JackSocketServerChannel::ClientAdd\n");
  77. int refnum = -1;
  78. *result = fServer->GetEngine()->ClientExternalOpen(name, &refnum, shared_engine, shared_client, shared_graph);
  79. if (*result == 0) {
  80. fSocketTable[fd].first = refnum;
  81. fRebuild = true;
  82. } else {
  83. jack_error("Cannot create new client");
  84. }
  85. }
  86. void JackSocketServerChannel::ClientRemove(int fd, int refnum)
  87. {
  88. pair<int, JackClientSocket*> elem = fSocketTable[fd];
  89. JackClientSocket* socket = elem.second;
  90. assert(socket);
  91. JackLog("JackSocketServerChannel::ClientRemove ref = %d\n", refnum);
  92. fSocketTable.erase(fd);
  93. socket->Close();
  94. delete socket;
  95. fRebuild = true;
  96. }
  97. void JackSocketServerChannel::ClientKill(int fd)
  98. {
  99. pair<int, JackClientSocket*> elem = fSocketTable[fd];
  100. JackClientSocket* socket = elem.second;
  101. int refnum = elem.first;
  102. assert(socket);
  103. JackLog("JackSocketServerChannel::ClientKill ref = %d\n", refnum);
  104. if (refnum == -1) { // Should never happen... correspond to a client that started the socket but never opened...
  105. JackLog("Client was not opened : probably correspond to server_check\n");
  106. } else {
  107. fServer->Notify(refnum, kDeadClient, 0);
  108. }
  109. fSocketTable.erase(fd);
  110. socket->Close();
  111. delete socket;
  112. fRebuild = true;
  113. }
  114. int JackSocketServerChannel::HandleRequest(int fd)
  115. {
  116. pair<int, JackClientSocket*> elem = fSocketTable[fd];
  117. JackClientSocket* socket = elem.second;
  118. assert(socket);
  119. // Read header
  120. JackRequest header;
  121. if (header.Read(socket) < 0) {
  122. jack_error("HandleRequest: cannot read header");
  123. return -1;
  124. }
  125. // Read data
  126. switch (header.fType) {
  127. case JackRequest::kClientCheck: {
  128. JackLog("JackRequest::kClientCheck\n");
  129. JackClientCheckRequest req;
  130. JackClientCheckResult res;
  131. if (req.Read(socket) == 0)
  132. res.fResult = fServer->GetEngine()->ClientCheck(req.fName, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
  133. if (res.Write(socket) < 0)
  134. jack_error("JackRequest::kClientCheck write error name = %s", req.fName);
  135. break;
  136. }
  137. case JackRequest::kClientOpen: {
  138. JackLog("JackRequest::ClientOpen\n");
  139. JackClientOpenRequest req;
  140. JackClientOpenResult res;
  141. if (req.Read(socket) == 0)
  142. ClientAdd(fd, req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult);
  143. if (res.Write(socket) < 0)
  144. jack_error("JackRequest::kClientOpen write error name = %s", req.fName);
  145. break;
  146. }
  147. case JackRequest::kClientClose: {
  148. JackLog("JackRequest::ClientClose\n");
  149. JackClientCloseRequest req;
  150. JackResult res;
  151. if (req.Read(socket) == 0)
  152. res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
  153. // No write: client is actually doing an "ServerAsyncCall", and not interested by the result
  154. ClientRemove(fd, req.fRefNum);
  155. break;
  156. }
  157. case JackRequest::kActivateClient: {
  158. JackActivateRequest req;
  159. JackResult res;
  160. JackLog("JackRequest::ActivateClient\n");
  161. if (req.Read(socket) == 0)
  162. res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum);
  163. if (res.Write(socket) < 0)
  164. jack_error("JackRequest::kActivateClient write error ref = %d", req.fRefNum);
  165. break;
  166. }
  167. case JackRequest::kDeactivateClient: {
  168. JackLog("JackRequest::DeactivateClient\n");
  169. JackDeactivateRequest req;
  170. JackResult res;
  171. if (req.Read(socket) == 0)
  172. res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
  173. if (res.Write(socket) < 0)
  174. jack_error("JackRequest::kDeactivateClient write error ref = %d", req.fRefNum);
  175. break;
  176. }
  177. case JackRequest::kRegisterPort: {
  178. JackLog("JackRequest::RegisterPort\n");
  179. JackPortRegisterRequest req;
  180. JackPortRegisterResult res;
  181. if (req.Read(socket) == 0)
  182. res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
  183. if (res.Write(socket) < 0)
  184. jack_error("JackRequest::kRegisterPort write error ref = %d", req.fRefNum);
  185. break;
  186. }
  187. case JackRequest::kUnRegisterPort: {
  188. JackLog("JackRequest::UnRegisterPort\n");
  189. JackPortUnRegisterRequest req;
  190. JackResult res;
  191. if (req.Read(socket) == 0)
  192. res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
  193. if (res.Write(socket) < 0)
  194. jack_error("JackRequest::kUnRegisterPort write error ref = %d", req.fRefNum);
  195. break;
  196. }
  197. case JackRequest::kConnectNamePorts: {
  198. JackLog("JackRequest::ConnectPorts\n");
  199. JackPortConnectNameRequest req;
  200. JackResult res;
  201. if (req.Read(socket) == 0)
  202. res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
  203. if (res.Write(socket) < 0)
  204. jack_error("JackRequest::kConnectNamePorts write error ref = %d", req.fRefNum);
  205. break;
  206. }
  207. case JackRequest::kDisconnectNamePorts: {
  208. JackLog("JackRequest::DisconnectPorts\n");
  209. JackPortDisconnectNameRequest req;
  210. JackResult res;
  211. if (req.Read(socket) == 0)
  212. res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
  213. if (res.Write(socket) < 0)
  214. jack_error("JackRequest::kDisconnectNamePorts write error ref = %d", req.fRefNum);
  215. break;
  216. }
  217. case JackRequest::kConnectPorts: {
  218. JackLog("JackRequest::ConnectPorts\n");
  219. JackPortConnectRequest req;
  220. JackResult res;
  221. if (req.Read(socket) == 0)
  222. res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
  223. if (res.Write(socket) < 0)
  224. jack_error("JackRequest::kConnectPorts write error ref = %d", req.fRefNum);
  225. break;
  226. }
  227. case JackRequest::kDisconnectPorts: {
  228. JackLog("JackRequest::DisconnectPorts\n");
  229. JackPortDisconnectRequest req;
  230. JackResult res;
  231. if (req.Read(socket) == 0)
  232. res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
  233. if (res.Write(socket) < 0)
  234. jack_error("JackRequest::kDisconnectPorts write error ref = %d", req.fRefNum);
  235. break;
  236. }
  237. case JackRequest::kSetBufferSize: {
  238. JackLog("JackRequest::SetBufferSize\n");
  239. JackSetBufferSizeRequest req;
  240. JackResult res;
  241. if (req.Read(socket) == 0)
  242. res.fResult = fServer->SetBufferSize(req.fBufferSize);
  243. if (res.Write(socket) < 0)
  244. jack_error("JackRequest::kSetBufferSize write error");
  245. break;
  246. }
  247. case JackRequest::kSetFreeWheel: {
  248. JackLog("JackRequest::SetFreeWheel\n");
  249. JackSetFreeWheelRequest req;
  250. JackResult res;
  251. if (req.Read(socket) == 0)
  252. res.fResult = fServer->SetFreewheel(req.fOnOff);
  253. if (res.Write(socket) < 0)
  254. jack_error("JackRequest::kSetFreeWheel write error");
  255. break;
  256. }
  257. case JackRequest::kReleaseTimebase: {
  258. JackLog("JackRequest::kReleaseTimebase\n");
  259. JackReleaseTimebaseRequest req;
  260. JackResult res;
  261. if (req.Read(socket) == 0)
  262. res.fResult = fServer->ReleaseTimebase(req.fRefNum);
  263. if (res.Write(socket) < 0)
  264. jack_error("JackRequest::kReleaseTimebase write error ref = %d", req.fRefNum);
  265. break;
  266. }
  267. case JackRequest::kSetTimebaseCallback: {
  268. JackLog("JackRequest::kSetTimebaseCallback\n");
  269. JackSetTimebaseCallbackRequest req;
  270. JackResult res;
  271. if (req.Read(socket) == 0)
  272. res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
  273. if (res.Write(socket) < 0)
  274. jack_error("JackRequest::kSetTimebaseCallback write error ref = %d", req.fRefNum);
  275. break;
  276. }
  277. case JackRequest::kGetInternalClientName: {
  278. JackLog("JackRequest::kGetInternalClientName\n");
  279. JackGetInternalClientNameRequest req;
  280. JackGetInternalClientNameResult res;
  281. if (req.Read(socket) == 0)
  282. res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
  283. if (res.Write(socket) < 0)
  284. jack_error("JackRequest::kGetInternalClientName write error ref = %d", req.fRefNum);
  285. break;
  286. }
  287. case JackRequest::kInternalClientHandle: {
  288. JackLog("JackRequest::kInternalClientHandle\n");
  289. JackInternalClientHandleRequest req;
  290. JackInternalClientHandleResult res;
  291. if (req.Read(socket) == 0)
  292. res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
  293. if (res.Write(socket) < 0)
  294. jack_error("JackRequest::kInternalClientHandle write error ref = %d", req.fRefNum);
  295. break;
  296. }
  297. case JackRequest::kInternalClientLoad: {
  298. JackLog("JackRequest::kInternalClientLoad\n");
  299. JackInternalClientLoadRequest req;
  300. JackInternalClientLoadResult res;
  301. if (req.Read(socket) == 0)
  302. res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, &res.fStatus);
  303. if (res.Write(socket) < 0)
  304. jack_error("JackRequest::kInternalClientLoad write error name = %s", req.fName);
  305. break;
  306. }
  307. case JackRequest::kInternalClientUnload: {
  308. JackLog("JackRequest::kInternalClientUnload\n");
  309. JackInternalClientUnloadRequest req;
  310. JackInternalClientUnloadResult res;
  311. if (req.Read(socket) == 0)
  312. res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
  313. if (res.Write(socket) < 0)
  314. jack_error("JackRequest::kInternalClientUnload write error ref = %d", req.fRefNum);
  315. break;
  316. }
  317. case JackRequest::kNotification: {
  318. JackLog("JackRequest::Notification\n");
  319. JackClientNotificationRequest req;
  320. if (req.Read(socket) == 0)
  321. fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
  322. break;
  323. }
  324. default:
  325. JackLog("Unknown request %ld\n", header.fType);
  326. break;
  327. }
  328. return 0;
  329. }
  330. void JackSocketServerChannel::BuildPoolTable()
  331. {
  332. if (fRebuild) {
  333. fRebuild = false;
  334. delete[] fPollTable;
  335. fPollTable = new pollfd[fSocketTable.size() + 1];
  336. JackLog("JackSocketServerChannel::BuildPoolTable size = %d\n", fSocketTable.size() + 1);
  337. // First fd is the server request socket
  338. fPollTable[0].fd = fRequestListenSocket.GetFd();
  339. fPollTable[0].events = POLLIN | POLLERR;
  340. // Next fd for clients
  341. map<int, pair<int, JackClientSocket*> >::iterator it;
  342. int i;
  343. for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
  344. JackLog("fSocketTable i = %ld fd = %ld\n", i, it->first);
  345. fPollTable[i].fd = it->first;
  346. fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
  347. }
  348. }
  349. }
  350. bool JackSocketServerChannel::Execute()
  351. {
  352. // Global poll
  353. if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
  354. jack_error("Engine poll failed err = %s request thread quits...", strerror(errno));
  355. return false;
  356. } else {
  357. // Poll all clients
  358. for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
  359. int fd = fPollTable[i].fd;
  360. JackLog("fPollTable i = %ld fd = %ld\n", i, fd);
  361. if (fPollTable[i].revents & ~POLLIN) {
  362. JackLog("Poll client error err = %s\n", strerror(errno));
  363. ClientKill(fd);
  364. } else if (fPollTable[i].revents & POLLIN) {
  365. if (HandleRequest(fd) < 0) {
  366. jack_error("Could not handle external client request");
  367. //ClientRemove(fd); TO CHECK
  368. }
  369. }
  370. }
  371. // Check the server request socket */
  372. if (fPollTable[0].revents & POLLERR) {
  373. jack_error("Error on server request socket err = %s", strerror(errno));
  374. //return false; TO CHECK
  375. }
  376. if (fPollTable[0].revents & POLLIN) {
  377. ClientCreate();
  378. }
  379. }
  380. BuildPoolTable();
  381. return true;
  382. }
  383. } // end of namespace