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.

887 lines
28KB

  1. /*
  2. Copyright (C) 2001-2003 Paul Davis
  3. Copyright (C) 2005-2012 Grame
  4. Copyright (C) 2013 Samsung Electronics
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU Lesser General Public License as published by
  7. the Free Software Foundation; either version 2.1 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. */
  17. #define LOG_TAG "JAMSHMSERVICE"
  18. #include <stddef.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <binder/MemoryHeapBase.h>
  24. #include <binder/IServiceManager.h>
  25. #include <binder/IPCThreadState.h>
  26. #include <utils/Log.h>
  27. #include <sys/stat.h>
  28. #include <sys/socket.h>
  29. #include <sys/types.h>
  30. #include <sys/un.h>
  31. #include <sys/wait.h>
  32. #include "BnAndroidShm.h"
  33. #include "AndroidShm.h"
  34. #include "JackConstants.h"
  35. #include <fcntl.h>
  36. #include <signal.h>
  37. #include <limits.h>
  38. #include <errno.h>
  39. #include <dirent.h>
  40. #include <sys/mman.h>
  41. #include <linux/ashmem.h>
  42. #include <cutils/ashmem.h>
  43. #include "JackError.h"
  44. // remove ALOGI log
  45. #define jack_d
  46. //#define jack_d ALOGI
  47. #define jack_error ALOGE
  48. #define MEMORY_SIZE 10*1024
  49. namespace android {
  50. jack_shmtype_t Shm::jack_shmtype = shm_ANDROID;
  51. /* The JACK SHM registry is a chunk of memory for keeping track of the
  52. * shared memory used by each active JACK server. This allows the
  53. * server to clean up shared memory when it exits. To avoid memory
  54. * leakage due to kill -9, crashes or debugger-driven exits, this
  55. * cleanup is also done when a new instance of that server starts.
  56. */
  57. /* per-process global data for the SHM interfaces */
  58. jack_shm_id_t Shm::registry_id; /* SHM id for the registry */
  59. jack_shm_fd_t Shm::registry_fd = JACK_SHM_REGISTRY_FD;
  60. jack_shm_info_t Shm::registry_info = {
  61. JACK_SHM_NULL_INDEX, 0, 0, { MAP_FAILED }
  62. };
  63. /* pointers to registry header and array */
  64. jack_shm_header_t *Shm::jack_shm_header = NULL;
  65. jack_shm_registry_t *Shm::jack_shm_registry = NULL;
  66. char Shm::jack_shm_server_prefix[JACK_SERVER_NAME_SIZE+1] = "";
  67. /* jack_shm_lock_registry() serializes updates to the shared memory
  68. * segment JACK uses to keep track of the SHM segments allocated to
  69. * all its processes, including multiple servers.
  70. *
  71. * This is not a high-contention lock, but it does need to work across
  72. * multiple processes. High transaction rates and realtime safety are
  73. * not required. Any solution needs to at least be portable to POSIX
  74. * and POSIX-like systems.
  75. *
  76. * We must be particularly careful to ensure that the lock be released
  77. * if the owning process terminates abnormally. Otherwise, a segfault
  78. * or kill -9 at the wrong moment could prevent JACK from ever running
  79. * again on that machine until after a reboot.
  80. */
  81. #define JACK_SEMAPHORE_KEY 0x282929
  82. #define JACK_SHM_REGISTRY_KEY JACK_SEMAPHORE_KEY
  83. #define JACK_REGISTRY_NAME "/jack-shm-registry"
  84. int Shm::semid = -1;
  85. pthread_mutex_t Shm::mutex = PTHREAD_MUTEX_INITIALIZER;
  86. //sp<IAndroidShm> Shm::mShmService;
  87. sp<IMemoryHeap> Shm::mShmMemBase[JACK_SHM_HEAP_ENOUGH_COUNT] = {0,};
  88. Shm* Shm::ref = NULL;
  89. Shm* Shm::Instantiate() {
  90. if(Shm::ref == NULL) {
  91. jack_d("shm::Instantiate is called");
  92. Shm::ref = new Shm;
  93. //AndroidShm::instantiate();
  94. }
  95. return ref;
  96. }
  97. Shm::Shm() { }
  98. Shm::~Shm() { }
  99. sp<IAndroidShm> Shm::getShmService(){
  100. return interface_cast<IAndroidShm>(defaultServiceManager()->getService(String16("com.samsung.android.jam.IAndroidShm")));
  101. }
  102. //sp<IAndroidShm>& Shm::getShmService() {
  103. // if (mShmService.get() == 0) {
  104. // sp<IServiceManager> sm = defaultServiceManager();
  105. // sp<IBinder> binder;
  106. // do {
  107. // binder = sm->getService(String16("com.samsung.android.jam.IAndroidShm"));
  108. // if (binder != 0)
  109. // break;
  110. // ALOGW("CameraService not published, waiting...");
  111. // usleep(500000); // 0.5 s
  112. // } while(true);
  113. // mShmService = interface_cast<IAndroidShm>(binder);
  114. // }
  115. // ALOGE_IF(mShmService==0, "no CameraService!?");
  116. // return mShmService;
  117. //}
  118. void Shm::shm_copy_from_registry (jack_shm_info_t* /*si*/, jack_shm_registry_index_t ) {
  119. // not used
  120. }
  121. void Shm::shm_copy_to_registry (jack_shm_info_t* /*si*/, jack_shm_registry_index_t*) {
  122. // not used
  123. }
  124. void Shm::jack_release_shm_entry (jack_shm_registry_index_t index) {
  125. /* the registry must be locked */
  126. jack_shm_registry[index].size = 0;
  127. jack_shm_registry[index].allocator = 0;
  128. memset (&jack_shm_registry[index].id, 0,
  129. sizeof (jack_shm_registry[index].id));
  130. jack_shm_registry[index].fd = 0;
  131. }
  132. int Shm::release_shm_info (jack_shm_registry_index_t index) {
  133. /* must NOT have the registry locked */
  134. if (jack_shm_registry[index].allocator == GetPID()) {
  135. if (jack_shm_lock_registry () < 0) {
  136. jack_error ("jack_shm_lock_registry fails...");
  137. return -1;
  138. }
  139. jack_release_shm_entry (index);
  140. jack_shm_unlock_registry ();
  141. jack_d ("release_shm_info: success!");
  142. }
  143. else
  144. jack_error ("release_shm_info: error!");
  145. return 0;
  146. }
  147. char* Shm::shm_addr (unsigned int fd) {
  148. if(fd >= JACK_SHM_HEAP_ENOUGH_COUNT) {
  149. jack_error("ignore to get memory buffer : index[%d] is too big", fd);
  150. return NULL;
  151. }
  152. sp<IAndroidShm> service = Shm::getShmService();
  153. if(service == NULL){
  154. jack_error("shm service is null");
  155. return NULL;
  156. }
  157. mShmMemBase[fd] = service->getBuffer(fd);
  158. if(mShmMemBase[fd] == NULL) {
  159. jack_error("fail to get memory buffer");
  160. return NULL;
  161. }
  162. return ((char *) mShmMemBase[fd]->getBase());
  163. }
  164. int Shm::shm_lock_registry (void) {
  165. pthread_mutex_lock (&mutex);
  166. return 0;
  167. }
  168. void Shm::shm_unlock_registry (void) {
  169. pthread_mutex_unlock (&mutex);
  170. }
  171. void Shm::release_shm_entry (jack_shm_registry_index_t index) {
  172. /* the registry must be locked */
  173. jack_shm_registry[index].size = 0;
  174. jack_shm_registry[index].allocator = 0;
  175. memset (&jack_shm_registry[index].id, 0,
  176. sizeof (jack_shm_registry[index].id));
  177. }
  178. void Shm::remove_shm (jack_shm_id_t *id) {
  179. int shm_fd = -1;
  180. jack_d("remove_id [%s]",(char*)id);
  181. if(!strcmp((const char*)id, JACK_REGISTRY_NAME)) {
  182. shm_fd = registry_fd;
  183. } else {
  184. for (int i = 0; i < MAX_SHM_ID; i++) {
  185. if(!strcmp((const char*)id, jack_shm_registry[i].id)) {
  186. shm_fd = jack_shm_registry[i].fd;
  187. break;
  188. }
  189. }
  190. }
  191. if (shm_fd >= 0) {
  192. sp<IAndroidShm> service = getShmService();
  193. if(service != NULL) {
  194. service->removeShm(shm_fd);
  195. } else {
  196. jack_error("shm service is null");
  197. }
  198. }
  199. jack_d ("[APA] jack_remove_shm : ok ");
  200. }
  201. int Shm::access_registry (jack_shm_info_t * ri) {
  202. jack_d("access_registry\n");
  203. /* registry must be locked */
  204. sp<IAndroidShm> service = getShmService();
  205. if(service == NULL){
  206. jack_error("shm service is null");
  207. return EINVAL;
  208. }
  209. int shm_fd = service->getRegistryIndex();
  210. strncpy (registry_id, JACK_REGISTRY_NAME, sizeof (registry_id) - 1);
  211. registry_id[sizeof (registry_id) - 1] = '\0';
  212. if(service->isAllocated(shm_fd) == FALSE) {
  213. //jack_error ("Cannot mmap shm registry segment (%s)",
  214. // strerror (errno));
  215. jack_error ("Cannot mmap shm registry segment");
  216. //close (shm_fd);
  217. ri->ptr.attached_at = NULL;
  218. registry_fd = JACK_SHM_REGISTRY_FD;
  219. return EINVAL;
  220. }
  221. ri->fd = shm_fd;
  222. registry_fd = shm_fd;
  223. ri->ptr.attached_at = shm_addr(shm_fd);
  224. if(ri->ptr.attached_at == NULL) {
  225. ALOGE("attached pointer is null !");
  226. jack_shm_header = NULL;
  227. jack_shm_registry = NULL;
  228. return 0;
  229. }
  230. /* set up global pointers */
  231. ri->index = JACK_SHM_REGISTRY_INDEX;
  232. jack_shm_header = (jack_shm_header_t*)(ri->ptr.attached_at);
  233. jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1);
  234. jack_d("jack_shm_header[%p],jack_shm_registry[%p]", jack_shm_header, jack_shm_registry);
  235. //close (shm_fd); // steph
  236. return 0;
  237. }
  238. int Shm::GetUID() {
  239. return geteuid();
  240. }
  241. int Shm::GetPID() {
  242. return getpid();
  243. }
  244. int Shm::jack_shm_lock_registry (void) {
  245. // TODO: replace semaphore to mutex
  246. pthread_mutex_lock (&mutex);
  247. return 0;
  248. }
  249. void Shm::jack_shm_unlock_registry (void) {
  250. // TODO: replace semaphore to mutex
  251. pthread_mutex_unlock (&mutex);
  252. return;
  253. }
  254. void Shm::shm_init_registry () {
  255. if(jack_shm_header == NULL)
  256. return;
  257. /* registry must be locked */
  258. memset (jack_shm_header, 0, JACK_SHM_REGISTRY_SIZE);
  259. jack_shm_header->magic = JACK_SHM_MAGIC;
  260. //jack_shm_header->protocol = JACK_PROTOCOL_VERSION;
  261. jack_shm_header->type = jack_shmtype;
  262. jack_shm_header->size = JACK_SHM_REGISTRY_SIZE;
  263. jack_shm_header->hdr_len = sizeof (jack_shm_header_t);
  264. jack_shm_header->entry_len = sizeof (jack_shm_registry_t);
  265. for (int i = 0; i < MAX_SHM_ID; ++i) {
  266. jack_shm_registry[i].index = i;
  267. }
  268. }
  269. void Shm::set_server_prefix (const char *server_name) {
  270. snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix),
  271. "jack-%d:%s:", GetUID(), server_name);
  272. }
  273. /* create a new SHM registry segment
  274. *
  275. * sets up global registry pointers, if successful
  276. *
  277. * returns: 0 if registry created successfully
  278. * nonzero error code if unable to allocate a new registry
  279. */
  280. int Shm::create_registry (jack_shm_info_t * ri) {
  281. jack_d("create_registry\n");
  282. /* registry must be locked */
  283. int shm_fd = 0;
  284. strncpy (registry_id, JACK_REGISTRY_NAME, sizeof (registry_id) - 1);
  285. registry_id[sizeof (registry_id) - 1] = '\0';
  286. sp<IAndroidShm> service = getShmService();
  287. if(service == NULL){
  288. jack_error("shm service is null");
  289. return EINVAL;
  290. }
  291. if((shm_fd = service->allocShm(JACK_SHM_REGISTRY_SIZE)) < 0) {
  292. jack_error("Cannot create shm registry segment");
  293. registry_fd = JACK_SHM_REGISTRY_FD;
  294. return EINVAL;
  295. }
  296. service->setRegistryIndex(shm_fd);
  297. /* set up global pointers */
  298. ri->fd = shm_fd;
  299. ri->index = JACK_SHM_REGISTRY_INDEX;
  300. registry_fd = shm_fd;
  301. ri->ptr.attached_at = shm_addr(shm_fd);
  302. ri->size = JACK_SHM_REGISTRY_SIZE;
  303. jack_shm_header = (jack_shm_header_t*)(ri->ptr.attached_at);
  304. jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1);
  305. jack_d("create_registry jack_shm_header[%p], jack_shm_registry[%p]", jack_shm_header, jack_shm_registry);
  306. /* initialize registry contents */
  307. shm_init_registry ();
  308. //close (shm_fd); // steph
  309. return 0;
  310. }
  311. int Shm::shm_validate_registry () {
  312. /* registry must be locked */
  313. if(jack_shm_header == NULL) {
  314. return -1;
  315. }
  316. if ((jack_shm_header->magic == JACK_SHM_MAGIC)
  317. //&& (jack_shm_header->protocol == JACK_PROTOCOL_VERSION)
  318. && (jack_shm_header->type == jack_shmtype)
  319. && (jack_shm_header->size == JACK_SHM_REGISTRY_SIZE)
  320. && (jack_shm_header->hdr_len == sizeof (jack_shm_header_t))
  321. && (jack_shm_header->entry_len == sizeof (jack_shm_registry_t))) {
  322. return 0; /* registry OK */
  323. }
  324. return -1;
  325. }
  326. int Shm::server_initialize_shm (int new_registry) {
  327. int rc;
  328. jack_d("server_initialize_shm\n");
  329. if (jack_shm_header)
  330. return 0; /* already initialized */
  331. if (shm_lock_registry () < 0) {
  332. jack_error ("jack_shm_lock_registry fails...");
  333. return -1;
  334. }
  335. rc = access_registry (&registry_info);
  336. if (new_registry) {
  337. remove_shm (&registry_id);
  338. rc = ENOENT;
  339. }
  340. switch (rc) {
  341. case ENOENT: /* registry does not exist */
  342. rc = create_registry (&registry_info);
  343. break;
  344. case 0: /* existing registry */
  345. if (shm_validate_registry () == 0)
  346. break;
  347. /* else it was invalid, so fall through */
  348. case EINVAL: /* bad registry */
  349. /* Apparently, this registry was created by an older
  350. * JACK version. Delete it so we can try again. */
  351. release_shm (&registry_info);
  352. remove_shm (&registry_id);
  353. if ((rc = create_registry (&registry_info)) != 0) {
  354. //jack_error ("incompatible shm registry (%s)",
  355. // strerror (errno));
  356. jack_error ("incompatible shm registry");
  357. //#ifndef USE_POSIX_SHM
  358. // jack_error ("to delete, use `ipcrm -M 0x%0.8x'", JACK_SHM_REGISTRY_KEY);
  359. //#endif
  360. }
  361. break;
  362. default: /* failure return code */
  363. break;
  364. }
  365. shm_unlock_registry ();
  366. return rc;
  367. }
  368. // here begin the API
  369. int Shm::register_server (const char *server_name, int new_registry) {
  370. int i, res = 0;
  371. jack_d("register_server new_registry[%d]\n", new_registry);
  372. set_server_prefix (server_name);
  373. if (server_initialize_shm (new_registry))
  374. return ENOMEM;
  375. if (shm_lock_registry () < 0) {
  376. jack_error ("jack_shm_lock_registry fails...");
  377. return -1;
  378. }
  379. /* See if server_name already registered. Since server names
  380. * are per-user, we register the unique server prefix string.
  381. */
  382. for (i = 0; i < MAX_SERVERS; i++) {
  383. if (strncmp (jack_shm_header->server[i].name,
  384. jack_shm_server_prefix,
  385. JACK_SERVER_NAME_SIZE) != 0)
  386. continue; /* no match */
  387. if (jack_shm_header->server[i].pid == GetPID()) {
  388. res = 0; /* it's me */
  389. goto unlock;
  390. }
  391. /* see if server still exists */
  392. if (kill (jack_shm_header->server[i].pid, 0) == 0) {
  393. res = EEXIST; /* other server running */
  394. goto unlock;
  395. }
  396. /* it's gone, reclaim this entry */
  397. memset (&jack_shm_header->server[i], 0,
  398. sizeof (jack_shm_server_t));
  399. }
  400. /* find a free entry */
  401. for (i = 0; i < MAX_SERVERS; i++) {
  402. if (jack_shm_header->server[i].pid == 0)
  403. break;
  404. }
  405. if (i >= MAX_SERVERS) {
  406. res = ENOSPC; /* out of space */
  407. goto unlock;
  408. }
  409. /* claim it */
  410. jack_shm_header->server[i].pid = GetPID();
  411. strncpy (jack_shm_header->server[i].name,
  412. jack_shm_server_prefix,
  413. JACK_SERVER_NAME_SIZE - 1);
  414. jack_shm_header->server[i].name[JACK_SERVER_NAME_SIZE - 1] = '\0';
  415. unlock:
  416. shm_unlock_registry ();
  417. return res;
  418. }
  419. int Shm::unregister_server (const char * /* server_name */) {
  420. int i;
  421. if (shm_lock_registry () < 0) {
  422. jack_error ("jack_shm_lock_registry fails...");
  423. return -1;
  424. }
  425. for (i = 0; i < MAX_SERVERS; i++) {
  426. if (jack_shm_header->server[i].pid == GetPID()) {
  427. memset (&jack_shm_header->server[i], 0,
  428. sizeof (jack_shm_server_t));
  429. }
  430. }
  431. shm_unlock_registry ();
  432. return 0;
  433. }
  434. int Shm::initialize_shm (const char *server_name) {
  435. int rc;
  436. if (jack_shm_header)
  437. return 0; /* already initialized */
  438. set_server_prefix (server_name);
  439. if (shm_lock_registry () < 0) {
  440. jack_error ("jack_shm_lock_registry fails...");
  441. return -1;
  442. }
  443. if ((rc = access_registry (&registry_info)) == 0) {
  444. if ((rc = shm_validate_registry ()) != 0) {
  445. jack_error ("Incompatible shm registry, "
  446. "are jackd and libjack in sync?");
  447. }
  448. }
  449. shm_unlock_registry ();
  450. return rc;
  451. }
  452. int Shm::initialize_shm_server (void) {
  453. // not used
  454. return 0;
  455. }
  456. int Shm::initialize_shm_client (void) {
  457. // not used
  458. return 0;
  459. }
  460. int Shm::cleanup_shm (void) {
  461. int i;
  462. int destroy;
  463. jack_shm_info_t copy;
  464. if (shm_lock_registry () < 0) {
  465. jack_error ("jack_shm_lock_registry fails...");
  466. return -1;
  467. }
  468. for (i = 0; i < MAX_SHM_ID; i++) {
  469. jack_shm_registry_t* r;
  470. r = &jack_shm_registry[i];
  471. memcpy (&copy, r, sizeof (jack_shm_info_t));
  472. destroy = FALSE;
  473. /* ignore unused entries */
  474. if (r->allocator == 0)
  475. continue;
  476. /* is this my shm segment? */
  477. if (r->allocator == GetPID()) {
  478. /* allocated by this process, so unattach
  479. and destroy. */
  480. release_shm (&copy);
  481. destroy = TRUE;
  482. } else {
  483. /* see if allocator still exists */
  484. if (kill (r->allocator, 0)) {
  485. if (errno == ESRCH) {
  486. /* allocator no longer exists,
  487. * so destroy */
  488. destroy = TRUE;
  489. }
  490. }
  491. }
  492. if (destroy) {
  493. int index = copy.index;
  494. if ((index >= 0) && (index < MAX_SHM_ID)) {
  495. remove_shm (&jack_shm_registry[index].id);
  496. release_shm_entry (index);
  497. }
  498. r->size = 0;
  499. r->allocator = 0;
  500. }
  501. }
  502. shm_unlock_registry ();
  503. return TRUE;
  504. }
  505. jack_shm_registry_t * Shm::get_free_shm_info () {
  506. /* registry must be locked */
  507. jack_shm_registry_t* si = NULL;
  508. int i;
  509. for (i = 0; i < MAX_SHM_ID; ++i) {
  510. if (jack_shm_registry[i].size == 0) {
  511. break;
  512. }
  513. }
  514. if (i < MAX_SHM_ID) {
  515. si = &jack_shm_registry[i];
  516. }
  517. return si;
  518. }
  519. int Shm::shmalloc (const char * /*shm_name*/, jack_shmsize_t size, jack_shm_info_t* si) {
  520. jack_shm_registry_t* registry;
  521. int shm_fd;
  522. int rc = -1;
  523. char name[SHM_NAME_MAX+1];
  524. if (shm_lock_registry () < 0) {
  525. jack_error ("jack_shm_lock_registry fails...");
  526. return -1;
  527. }
  528. sp<IAndroidShm> service = getShmService();
  529. if(service == NULL){
  530. rc = errno;
  531. jack_error("shm service is null");
  532. goto unlock;
  533. }
  534. if ((registry = get_free_shm_info ()) == NULL) {
  535. jack_error ("shm registry full");
  536. goto unlock;
  537. }
  538. snprintf (name, sizeof (name), "/jack-%d-%d", GetUID(), registry->index);
  539. if (strlen (name) >= sizeof (registry->id)) {
  540. jack_error ("shm segment name too long %s", name);
  541. goto unlock;
  542. }
  543. if((shm_fd = service->allocShm(size)) < 0) {
  544. rc = errno;
  545. jack_error ("Cannot create shm segment %s", name);
  546. goto unlock;
  547. }
  548. //close (shm_fd);
  549. registry->size = size;
  550. strncpy (registry->id, name, sizeof (registry->id) - 1);
  551. registry->id[sizeof (registry->id) - 1] = '\0';
  552. registry->allocator = GetPID();
  553. registry->fd = shm_fd;
  554. si->fd = shm_fd;
  555. si->index = registry->index;
  556. si->ptr.attached_at = MAP_FAILED; /* not attached */
  557. rc = 0; /* success */
  558. jack_d ("[APA] jack_shmalloc : ok ");
  559. unlock:
  560. shm_unlock_registry ();
  561. return rc;
  562. }
  563. void Shm::release_shm (jack_shm_info_t* /*si*/) {
  564. // do nothing
  565. }
  566. void Shm::release_lib_shm (jack_shm_info_t* /*si*/) {
  567. // do nothing
  568. }
  569. void Shm::destroy_shm (jack_shm_info_t* si) {
  570. /* must NOT have the registry locked */
  571. if (si->index == JACK_SHM_NULL_INDEX)
  572. return; /* segment not allocated */
  573. remove_shm (&jack_shm_registry[si->index].id);
  574. release_shm_info (si->index);
  575. }
  576. int Shm::attach_shm (jack_shm_info_t* si) {
  577. jack_shm_registry_t *registry = &jack_shm_registry[si->index];
  578. if((si->ptr.attached_at = shm_addr(registry->fd)) == NULL) {
  579. jack_error ("Cannot mmap shm segment %s", registry->id);
  580. close (si->fd);
  581. return -1;
  582. }
  583. return 0;
  584. }
  585. int Shm::attach_lib_shm (jack_shm_info_t* si) {
  586. int res = attach_shm(si);
  587. if (res == 0)
  588. si->size = jack_shm_registry[si->index].size; // Keep size in si struct
  589. return res;
  590. }
  591. int Shm::attach_shm_read (jack_shm_info_t* si) {
  592. jack_shm_registry_t *registry = &jack_shm_registry[si->index];
  593. if((si->ptr.attached_at = shm_addr(registry->fd)) == NULL) {
  594. jack_error ("Cannot mmap shm segment %s", registry->id);
  595. close (si->fd);
  596. return -1;
  597. }
  598. return 0;
  599. }
  600. int Shm::attach_lib_shm_read (jack_shm_info_t* si) {
  601. int res = attach_shm_read(si);
  602. if (res == 0)
  603. si->size = jack_shm_registry[si->index].size; // Keep size in si struct
  604. return res;
  605. }
  606. int Shm::resize_shm (jack_shm_info_t* si, jack_shmsize_t size) {
  607. jack_shm_id_t id;
  608. /* The underlying type of `id' differs for SYSV and POSIX */
  609. memcpy (&id, &jack_shm_registry[si->index].id, sizeof (id));
  610. release_shm (si);
  611. destroy_shm (si);
  612. if (shmalloc ((char *) id, size, si)) {
  613. return -1;
  614. }
  615. return attach_shm (si);
  616. }
  617. void Shm::jack_shm_copy_from_registry (jack_shm_info_t* si, jack_shm_registry_index_t t) {
  618. Shm::Instantiate()->shm_copy_from_registry(si,t);
  619. }
  620. void Shm::jack_shm_copy_to_registry (jack_shm_info_t* si, jack_shm_registry_index_t* t) {
  621. Shm::Instantiate()->shm_copy_to_registry(si,t);
  622. }
  623. int Shm::jack_release_shm_info (jack_shm_registry_index_t t) {
  624. return Shm::Instantiate()->release_shm_info(t);
  625. }
  626. char* Shm::jack_shm_addr (jack_shm_info_t* si) {
  627. if(si != NULL) {
  628. return (char*)si->ptr.attached_at;
  629. } else {
  630. jack_error ("jack_shm_addr : jack_shm_info_t is NULL!");
  631. return NULL;
  632. }
  633. }
  634. int Shm::jack_register_server (const char *server_name, int new_registry) {
  635. return Shm::Instantiate()->register_server(server_name, new_registry);
  636. }
  637. int Shm::jack_unregister_server (const char *server_name) {
  638. return Shm::Instantiate()->unregister_server(server_name);
  639. }
  640. int Shm::jack_initialize_shm (const char *server_name) {
  641. return Shm::Instantiate()->initialize_shm(server_name);
  642. }
  643. int Shm::jack_initialize_shm_server (void) {
  644. return Shm::Instantiate()->initialize_shm_server();
  645. }
  646. int Shm::jack_initialize_shm_client () {
  647. return Shm::Instantiate()->initialize_shm_client();
  648. }
  649. int Shm::jack_cleanup_shm (void) {
  650. return Shm::Instantiate()->cleanup_shm();
  651. }
  652. int Shm::jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result) {
  653. return Shm::Instantiate()->shmalloc(shm_name, size, result);
  654. }
  655. void Shm::jack_release_shm (jack_shm_info_t* si) {
  656. Shm::Instantiate()->release_shm(si);
  657. }
  658. void Shm::jack_release_lib_shm (jack_shm_info_t* si) {
  659. Shm::Instantiate()->release_lib_shm(si);
  660. }
  661. void Shm::jack_destroy_shm (jack_shm_info_t* si) {
  662. Shm::Instantiate()->destroy_shm(si);
  663. }
  664. int Shm::jack_attach_shm (jack_shm_info_t* si) {
  665. return Shm::Instantiate()->attach_shm(si);
  666. }
  667. int Shm::jack_attach_lib_shm (jack_shm_info_t* si) {
  668. return Shm::Instantiate()->attach_lib_shm(si);
  669. }
  670. int Shm::jack_attach_shm_read (jack_shm_info_t* si) {
  671. return Shm::Instantiate()->attach_shm_read(si);
  672. }
  673. int Shm::jack_attach_lib_shm_read (jack_shm_info_t* si) {
  674. return Shm::Instantiate()->attach_lib_shm_read(si);
  675. }
  676. int Shm::jack_resize_shm (jack_shm_info_t* si, jack_shmsize_t size) {
  677. return Shm::Instantiate()->resize_shm(si, size);
  678. }
  679. };
  680. void jack_shm_copy_from_registry (jack_shm_info_t* si, jack_shm_registry_index_t t) {
  681. android::Shm::jack_shm_copy_from_registry(si, t);
  682. }
  683. void jack_shm_copy_to_registry (jack_shm_info_t* si, jack_shm_registry_index_t* t) {
  684. android::Shm::jack_shm_copy_to_registry(si, t);
  685. }
  686. int jack_release_shm_info (jack_shm_registry_index_t t) {
  687. return android::Shm::jack_release_shm_info(t);
  688. }
  689. char* jack_shm_addr (jack_shm_info_t* si) {
  690. return android::Shm::jack_shm_addr(si);
  691. }
  692. int jack_register_server (const char *server_name, int new_registry) {
  693. return android::Shm::jack_register_server(server_name, new_registry);
  694. }
  695. int jack_unregister_server (const char *server_name) {
  696. return android::Shm::jack_unregister_server(server_name);
  697. }
  698. int jack_initialize_shm (const char *server_name) {
  699. return android::Shm::jack_initialize_shm(server_name);
  700. }
  701. int jack_initialize_shm_server (void) {
  702. return android::Shm::jack_initialize_shm_server();
  703. }
  704. int jack_initialize_shm_client (void) {
  705. return android::Shm::jack_initialize_shm_client();
  706. }
  707. int jack_cleanup_shm (void) {
  708. return android::Shm::jack_cleanup_shm();
  709. }
  710. int jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* result) {
  711. return android::Shm::jack_shmalloc(shm_name, size, result);
  712. }
  713. void jack_release_shm (jack_shm_info_t* si) {
  714. android::Shm::jack_release_shm(si);
  715. }
  716. void jack_release_lib_shm (jack_shm_info_t* si) {
  717. android::Shm::jack_release_lib_shm(si);
  718. }
  719. void jack_destroy_shm (jack_shm_info_t* si) {
  720. android::Shm::jack_destroy_shm(si);
  721. }
  722. int jack_attach_shm (jack_shm_info_t* si) {
  723. return android::Shm::jack_attach_shm(si);
  724. }
  725. int jack_attach_lib_shm (jack_shm_info_t* si) {
  726. return android::Shm::jack_attach_lib_shm(si);
  727. }
  728. int jack_attach_shm_read (jack_shm_info_t* si) {
  729. return android::Shm::jack_attach_shm_read(si);
  730. }
  731. int jack_attach_lib_shm_read (jack_shm_info_t* si) {
  732. return android::Shm::jack_attach_lib_shm_read(si);
  733. }
  734. int jack_resize_shm (jack_shm_info_t* si, jack_shmsize_t size) {
  735. return android::Shm::jack_resize_shm(si, size);
  736. }
  737. void jack_instantiate() {
  738. android::AndroidShm::instantiate();
  739. }